> For the complete documentation index, see [llms.txt](https://docs.informationhub.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.informationhub.io/project/tables/create-table.md).

# Create a Table

To start storing data in your project, you first need to create a table and define its columns.

## Create the table

1. Open your project and click **Tables** in the sidebar.
2. Click the **+** button to open the create table dialog.
3. Enter a name for your table.
4. The primary key is set up automatically as an auto-incrementing integer column called `id`. You can rename it if needed. To use a human-readable ID instead (for example `OBS-1`), assign a key generator to the primary key column after creating the table - see **Key generators** below.
5. Click **Create**.

<figure><img src="/files/PfFMWyH92uel7LsuybHq" alt="The create table dialog"><figcaption><p>Creating a new table</p></figcaption></figure>

Your table is created with just the primary key column. Next, add the columns you need.

## Add columns

1. In the table view, click the **+** button on the table header (or click **ADD** in the toolbar and select **Add Column**).
2. Enter a name for the column.
3. Select a data type from the dropdown.
4. Optionally toggle **Required** to prevent the field from being left empty.
5. Optionally toggle **Unique** to prevent duplicate values in this column.
6. Optionally select a **Key Generator** to auto-populate the primary key with generated values (see below).
7. To add more columns at the same time, click **Add another column** and fill in the next row.
8. Click **Save** when you are done.

<figure><img src="/files/5X9vVM6SykZwaob6Optb" alt="Adding a column to a table"><figcaption><p>Adding a column</p></figcaption></figure>

{% hint style="info" %}
You can add multiple columns in one go. Use the **Add another column** button to add extra rows before saving, so you only need to submit the form once.
{% endhint %}

## Column types

Choose the right data type for each column. Using the correct type prevents data entry errors and makes analysis easier.

### Text

Stores free text of any length. Use it for names, descriptions, codes, notes, or any value that does not fit a more specific type. Stored as `TEXT` in the database. Text can also be used as a primary key.

### Integer

Stores whole numbers with no decimal part. Use it for counts, IDs, or any value that is always a round number. Stored as `INT`. Integer columns can be set to **auto-increment** when used as the primary key.

### Real

Stores decimal numbers at standard precision (roughly 6 significant decimal places). Use it for measurements where exact precision beyond 6 digits is not needed - for example, pH readings, percentages, or short coordinates.

### Double Precision

Stores decimal numbers at high precision (up to 15 significant decimal places). Use it when accuracy matters - for example, GPS coordinates, financial figures, or scientific measurements. Use Double Precision over Real when in doubt.

### Yes / No

Stores a boolean true/false value. Displayed as a toggle in the data entry form. Use it for binary questions: "Collected?", "Verified?", "Active?".

### File

Stores a reference to one or more files. Each uploaded file is stored in your project's **Storage** and the cell holds the file names and their storage URLs. In the table grid, File cells render as clickable links that open the file in a new tab.

{% hint style="info" %}
**File columns are text under the hood.** The cell value is a text string in `filename[url],` format. This means you can also manually type an external URL (such as a DOI link or external resource) using the same format - for example: `Paper[https://doi.org/10.xxxx/example]`. The cell will render it as a clickable link without any upload required.
{% endhint %}

### Dropdown

Stores a selection from a predefined list of options. The options are defined when linking the column to a form question. Stored as text internally. Use it for fields with a fixed set of valid values - for example, site names, status codes, or category labels.

### Foreign Key

Stores a reference to a row in another table in the same project. The stored value is the primary key of the referenced row. Use it to link records across tables and avoid data duplication - for example, linking an observation row to a row in a Sites table instead of repeating the site name on every row.

When adding or editing a row, Foreign Key columns present a search interface to find and select the referenced record.

### JSON

Stores structured data as a JSON value in a single cell. Use it when you need to record a collection of related attributes that do not fit a flat column structure. The form builder's **JSON** question type links to this column type.

### Tabular

Stores multiple rows of structured data within a single cell. Use it for forms where respondents need to enter a variable number of sub-records in one submission - for example, multiple measurements taken at one site visit. Linked to the **Tabular** question type.

***

## Edit a column

To change a column's name, type, or settings after it has been created:

1. In the table view, click the **pencil icon** on the column header you want to edit.
2. Update the column name, type, Required/Unique toggles, or key generator assignment.
3. Click **Save**.

{% hint style="warning" %}
If you change a column's data type, a warning will appear if the change could affect existing data. Review the warning carefully before confirming.
{% endhint %}

You can also delete a column permanently from the edit column form using the **Delete Column** button. This cannot be undone.

***

## Key generators

A key generator auto-populates the primary key column with values based on a template pattern. This is useful for human-readable sample IDs, serial numbers, or any code that follows a consistent format.

{% hint style="info" %}
If your key generator template includes literal text (for example `OBS-{autoincrement}` or `SP-{uuid[0:8]}`), the primary key column type must be **Text**, not **Integer**. Open **Edit Column** on the primary key column and change its type to Text before assigning the generator.
{% endhint %}

Key generators are **project-level** - one generator can be reused across multiple tables. They are assigned to the primary key column of a table at creation time or by editing the primary key column.

### Managing key generators

Key generators are managed from the **Tables list** page:

1. Click **Tables** in the project sidebar.
2. Click the **Key Generators** button in the toolbar.
3. Click **+** to create a new generator.
4. Enter a **Name**, an optional **Description**, and a **Template** string (see tokens below).
5. Click **Create**.

To edit or delete an existing key generator, use the edit (pencil) or delete icons next to each entry in the list.

Once a key generator exists, assign it to a table's primary key column when creating the table, or by opening **Edit Column** on the primary key column.

### Template tokens

Templates are strings that mix literal text with tokens in `{...}` syntax. Tokens are replaced with generated values when a new row is inserted.

| Token             | What it produces                                | Example output                         |
| ----------------- | ----------------------------------------------- | -------------------------------------- |
| `{autoincrement}` | An atomically incrementing integer (1, 2, 3...) | `42`                                   |
| `{uuid}`          | A random v4 UUID                                | `f47ac10b-58cc-4372-a567-0e02b2c3d479` |
| `{cuid}`          | A collision-resistant unique ID                 | `clh3z8k0v0000qzrmabcd1234`            |
| `{date}`          | Current date as `YYYY-MM-DD`                    | `2026-05-26`                           |
| `{date:FORMAT}`   | Current date in a custom moment.js format       | `{date:YYYYMMDD}` → `20260526`         |
| `{time}`          | Current time as `HH:mm:ss`                      | `14:32:07`                             |
| `{time:FORMAT}`   | Current time in a custom moment.js format       | `{time:HHmm}` → `1432`                 |
| `{datetime}`      | Current date and time (ISO 8601)                | `2026-05-26T14:32:07+00:00`            |
| `{columnId}`      | Value of another column in the same row         | `Site Alpha`                           |

### Slicing token output

Any token can be sliced to take only part of the generated value, using Python-style `[start:end]` notation immediately after the token name:

* `{uuid[0:8]}` - first 8 characters of a UUID
* `{cuid[0:12]}` - first 12 characters of a CUID
* `{autoincrement[0:4]}` - first 4 digits of the counter

### Formatters

Add `:lower`, `:upper`, or (for column references) `:slug` after the token to transform the output:

* `{uuid:upper}` - UUID in uppercase
* `{date:YYYYMMDD}` - date formatted as `20260526` (the `:FORMAT` string is the formatter for date/time tokens)
* `{siteColumnId:slug}` - column value lowercased with spaces replaced by hyphens

### Working examples

**Sequential observation IDs**

```
OBS-{autoincrement}
```

Produces: `OBS-1`, `OBS-2`, `OBS-3`, ...

**Date-prefixed short UUID**

```
{date:YYYYMMDD}-{uuid[0:8]:upper}
```

Produces: `20260526-F47AC10B`, `20260526-A3B2C1D0`, ...

**Site-prefixed sequential ID** (where `clm8abc123def456xyz` is the column ID of the `site` column)

```
{clm8abc123def456xyz:slug}-{autoincrement}
```

Produces: `site-alpha-1`, `site-beta-2`, ...

**Short CUID for compact IDs**

```
SP-{cuid[0:8]}
```

Produces: `SP-clh3z8k0`, `SP-clh3z8k1`, ...

{% hint style="info" %}
To find a column's ID for use in a template, look at the column's URL when editing it, or ask a developer with database access. Column IDs are 20-40 alphanumeric characters.
{% endhint %}

{% hint style="warning" %}
Key generators can only be assigned to **primary key columns**. They apply to new rows only - existing rows keep their original primary keys.
{% endhint %}

***

## Table settings

The **Settings** button in the table toolbar opens the table settings page, where you can:

* **Rename the table** - update the table name and click Save.
* **Clear all data** - deletes every row in the table but keeps all the columns and structure intact.
* **Delete the table** - permanently removes the table and all its data.

{% hint style="warning" %}
**Clear all data** and **Delete table** are permanent actions and cannot be undone. Export your data first if you need a backup.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.informationhub.io/project/tables/create-table.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
