> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alpha.new/llms.txt
> Use this file to discover all available pages before exploring further.

# Browse, edit and query data

> Edit tables like a spreadsheet, read their structure, and run SQL, all inside the Database tab.

The Database tab's browser shows the tables of the database you pick in your session's PostgreSQL, in three views. **Data** is an editable grid, **Structure** shows how a table is built, and **SQL** runs queries against the whole database. To switch the database on, pick another database, connect from code or export a dump, see [Your session's database](https://docs.alpha.new/workspace/database.md).

![The Harbor bookings session with the Database tab in front. The tab strip reads Plan, Preview, Shell, Database with its ×, then the file tabs README.md and server.js and the round + button, with the GitHub, Share, Publish and files buttons at the right. The toolbar reads PostgreSQL 16.15 · 2 databases · up 3 h in small grey type on the left, shows the database picker pill with a blue dot, a database icon, the name forge and a chevron in the middle, and ends with Connect with a plug icon and the ⋯ Database actions button on the right. The left column has a Tables filter box above the list bookings 8, classes 3, instructors 3, members 6 and schema\_migrations 1, with instructors selected and 5 tables · 1 ext at the bottom. Above the grid sits the view switch reading Data, Structure and SQL, with Data active and the table name instructors beside it. The grid toolbar shows Filter and a Search rows box on the left, and Refresh, Delete and Add row on the right. The column headers read id with a key icon, name, email and created\_at, with their types uuid, varchar, varchar and timestamptz in small grey text. Three rows follow: Maya Chen, maya.chen@harbor.example; Oliver Brooks, oliver.brooks@harbor.example; and Sophie Laurent, sophie.laurent@harbor.example, each with a uuid and a created\_at of 2026-10-27T20:30:21 cut off at the right edge. The footer reads 1–3 of 3 · 0 ms beside the Previous page and Next page arrows, with the page-size picker reading 100 rows on the right. The chat on the left shows the answered The agent has questions card and a Proposed plan card for Automatic class waitlist.](https://mintcdn.com/lyzr-15a99e0f/ObBpayiae_4aNgzN/images/workspace/database-grid.png?fit=max\&auto=format\&n=ObBpayiae_4aNgzN\&q=85\&s=be3aa52488ba14f97633baaffd2ee1a5)

The toolbar holds the server summary, the database picker and Connect; the open table's rows fill the grid below.

## Find the rows you need

The column on the left lists the database's tables, then its views (eye icon). Tables outside the `public` schema are grouped under their schema's name. A count prefixed with `~` is PostgreSQL's estimate, not an exact count. Type in **Tables** to narrow the list, and click a table to open it. While this browser tab stays open, Alpha remembers which table you had open in each database, and where you left each table: its page, sort, filters and search.

In the **Data** view, the toolbar narrows the rows. Alpha runs each change as a query on the database, so sorting and filtering cover the whole table, not only the page on screen.

| To | Do this |
| - | - |
| Sort | Click a column header. Click again to reverse the order, and a third time to clear it. <kbd>⌘</kbd>-click another header (Ctrl-click on Windows and Linux) to sort by it as well, up to four columns. |
| Filter | Click **Filter**, pick a column, an operator and a value, then **Apply**. **Add filter** stacks another condition, and every condition must match. Each filter shows as a chip; click a chip to remove it (**Remove filter**), or click **Clear** in the popover. |
| Search | Type in **Search rows**. Alpha matches the text anywhere in any column, ignoring case. |
| Page through | Use **Previous page** and **Next page** in the footer. The picker on the right shows **50 rows**, **100 rows**, **250 rows** or **500 rows** per page. It starts at 100, and this browser remembers your choice. |
| Copy a value | Click a cell and press <kbd>⌘</kbd><kbd>C</kbd>. |

Hover a column header to see its full type, and the table it points to if it's a foreign key.

The **Filter** operators:

| Operator | Matches rows where the column… |
| - | - |
| **=**, **≠**, **>**, **≥**, **\<**, **≤** | compares to the value as stated |
| **contains** | includes the text anywhere, ignoring case |
| **LIKE**, **ILIKE** | matches a PostgreSQL pattern, such as `%harbor%`. **ILIKE** ignores case. |
| **in list** | equals one of a comma-separated list, such as `a, b, c` |
| **is NULL**, **is not NULL** | is empty, or isn't. These take no value. |

## Edit rows like a spreadsheet

Changes in the grid aren't written one cell at a time. They're staged, then saved together in one transaction, so a save either applies completely or not at all.

| To | Do this |
| - | - |
| Change a cell | Double-click it, or select it and press <kbd>Enter</kbd>. Type, then press <kbd>Enter</kbd> or <kbd>Tab</kbd>, or click outside, to keep the edit. <kbd>Shift</kbd><kbd>Enter</kbd> adds a line break. <kbd>Esc</kbd> cancels. |
| Set NULL or the default | In the cell editor, click the **NULL** chip, or **DEFAULT** to let PostgreSQL fill in the column's default. Each chip appears only where the column allows it. |
| Add a row | Click **Add row**. A green row opens at the bottom, with the editor open on the first column that has no default. Columns with a default, such as an identity or serial key, show **DEFAULT** and are filled when you save. A column you must fill shows **required**. |
| Delete rows | Tick the rows' checkboxes and click **Delete**. They turn red and struck through. Select them again and click **Undelete** to keep them. |
| Save | Click **Save** with the count, such as **Save 3 changes**. A green bar confirms, for example "Saved — 1 updated, 1 added, 1 deleted." |
| Throw changes away | Click **Discard** ("Discard all changes"). |

If PostgreSQL rejects a save, nothing is applied. The row that failed is outlined in red, the error shows above the grid, and your changes stay staged so you can fix them and save again. One save takes at most 1,000 changes.

Staged edits survive switching between Data, Structure and SQL. The badge in the header, such as "3 unsaved changes", takes you back to them. While edits are unsaved, sorting, the paging arrows and the page-size picker are locked, and hovering the row count or the picker shows "Save or discard your changes first". **Refresh** gives way to **Discard** and **Save**, and **Refresh tables and rows** under the table list waits too. Opening another table asks "Discard 3 unsaved changes in bookings and open classes?", with **Keep editing** and **Discard**.

Some tables can't be edited, and the footer says why:

| Footer chip | Meaning |
| - | - |
| **read-only** | A view, a materialized view or a foreign table. The chip's tooltip reads "Views and foreign tables are read-only here". |
| **no primary key** | You can edit, but Alpha finds each row by its physical position, which PostgreSQL can change during cleanup (`VACUUM`). Add a primary key for safe editing. |

Generated columns, and identity columns that PostgreSQL always fills, can't be typed into. A read or save that waits more than 5 seconds for a lock gives up. This usually means the agent is running a migration on that table, so try again once it finishes.

## Read a table's structure

**Structure** shows how the open table is built. **Columns** lists each column with its type, chips such as **pk**, **not null**, **unique**, **identity** and **generated**, and its default or the table it points to. **Indexes** and **Constraints** (foreign keys, unique and check constraints) follow.

![The Structure view of the instructors table, with instructors selected in the tables list. The heading reads instructors, then table · 3 rows · 40.0 KB. The COLUMNS section, with the count 4, lists id with a key icon, the type uuid, a pk chip and default gen\_random\_uuid(); name, varchar(100), not null; email, varchar(254), not null and unique; and created\_at, timestamptz, not null, default now(). The INDEXES section, with the count 2, lists instructors\_email\_key, marked unique, USING btree (email), and instructors\_pkey, marked primary, USING btree (id). The CONSTRAINTS section, with the count 3, lists instructors\_email\_key, unique, (email), and the check constraints instructors\_email\_check and instructors\_name\_check with their CHECK expressions. The DEFINITION section, with a copy button, starts create table instructors ( and is cut off at the bottom.](https://mintcdn.com/lyzr-15a99e0f/ObBpayiae_4aNgzN/images/workspace/database-structure.png?fit=max\&auto=format\&n=ObBpayiae_4aNgzN\&q=85\&s=c30df0fc6b68dfa2cb54f09c4d21e616)

Columns lists each column's type, chips and default; Indexes, Constraints and Definition follow.

**Definition** is rebuilt from PostgreSQL's catalog, not dumped byte for byte. Click **Copy SQL** to copy it.

> [!TIP]
>
> Paste the copied definition into the composer with the change you want, such as "Add a waitlist\_position column to this table." The agent then starts from the real schema, not from its memory of it.

## Run SQL

**SQL** opens an editor on the whole database, with completions for its tables and columns. Write a query and click **Run**, or press <kbd>⌘</kbd><kbd>Enter</kbd>. If you select part of the text, only the selection runs. While the editor is empty it suggests a query for the open table; click the suggestion to insert it.

![The Database tab in the SQL view, with the database name forge beside the Data, Structure and SQL switch and the tables list on the left. The editor holds one query: SELECT c.title, c.capacity, count(b.id) AS booked, c.capacity - count(b.id) AS seats\_left FROM classes c LEFT JOIN bookings b ON b.class\_id = c.id GROUP BY c.id ORDER BY c.class\_date;. The bar below reads Run with its shortcut, then SELECT, 3 rows and 1 ms. The results grid has the columns title, capacity, booked and seats\_left, with their types varchar, int4, int8 and int8, and three rows: Beginner Dinghy 8, 4, 4; Intermediate Keelboat 6, 2, 4; and Sunset Sail 10, 2, 8.](https://mintcdn.com/lyzr-15a99e0f/ObBpayiae_4aNgzN/images/workspace/database-sql.png?fit=max\&auto=format\&n=ObBpayiae_4aNgzN\&q=85\&s=f5834605ed6f504c6814ef387ddacda2)

The bar between the editor and the results gives the command, the row count and the time.

| What you see | Meaning |
| - | - |
| The command, the row count and the time, such as "SELECT 3 rows · 1 ms" | The query ran. Statements that return no rows show their command, such as `UPDATE 3`, and "no result set". |
| A **first 500 rows** chip | The result had more rows. Only the first 500 are shown, so add a `LIMIT` or a filter. |
| A red message, with a red marker in the editor | PostgreSQL refused the query. The marker sits where it found the problem, and its **DETAIL** and **HINT** lines show below. |
| A message at the far right of the bar | The last notice PostgreSQL sent, such as a warning from `DROP TABLE IF EXISTS`. |

Each query runs on its own and commits straight away. A script of several statements runs as one transaction, so all of it applies or none does. A query is stopped after 55 seconds. After any statement that isn't a read, such as a `CREATE TABLE` or an `INSERT`, the table list and the open table's rows refresh by themselves.

Drag the bar to give the editor or the results more room. What you've typed is kept in this browser, per database.

> [!WARNING]
>
> SQL in a session's database runs with full rights over it, and on a production database with the same rights as your app. There's no undo. `DROP`, `DELETE` and `TRUNCATE` take effect the moment they run, and your app sees the change at once. Export a dump first if you might want the data back; [Your session's database](https://docs.alpha.new/workspace/database.md) shows how.

## What if the database has no tables?

A database with no tables says "No tables in" followed by the database's name, with "Ask the agent to create your schema — it already has DATABASE\_URL — or write the SQL yourself." **Open SQL** takes you to the editor. The agent is usually the faster route, because it writes the migration into your app's code as well.

Try this

```text theme={"system"}
Create the schema for Harbor bookings: members, classes, instructors and bookings, with foreign keys and sensible defaults. Write it as a migration in the app, run it, and seed a week of sample classes.
```

Alpha will:

1. Write a migration file in your app's code and run it against the session's database.
2. Insert sample rows, so the **Data** view has something to show.
3. Tell you which tables it created. If the Database tab was already open, click **Refresh tables and rows** under the table list to see them.

> [!NOTE]
>
> The Database tab is for the session's owner. [People you share the session with](https://docs.alpha.new/sharing.md) don't see it. The same three views also open on a published app's production database, chosen in the database picker; saves and SQL there change your live app's data. See [Production database and sign-in](https://docs.alpha.new/publish/production-data.md).

## Next steps

> **[Your session's database](https://docs.alpha.new/workspace/database.md)**
>
> Switch PostgreSQL on, add a second database, connect from code, or export, import and reset.

> **[Production database and sign-in](https://docs.alpha.new/publish/production-data.md)**
>
> Your published app gets its own empty database. Bring the session's tables over when you're ready.

> **[The Shell](https://docs.alpha.new/workspace/shell.md)**
>
> Run `psql` against the same database from a terminal on the session's machine.

> **[Add a database and sign-in, then go to production](https://docs.alpha.new/guides/data-app.md)**
>
> A guided build that takes Harbor's data from the session all the way to production.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.