Skip to main content
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.
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.

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. Hover a column header to see its full type, and the table it points to if it’s a foreign key. The Filter operators:

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. 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: 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.

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.
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 ⌘Enter. 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.

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

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.
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 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. 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.
The Database tab is for the session’s owner. People you share the session with 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.

Next steps

Your session's database

Switch PostgreSQL on, add a second database, connect from code, or export, import and reset.

Production database and sign-in

Your published app gets its own empty database. Bring the session’s tables over when you’re ready.

The Shell

Run psql against the same database from a terminal on the session’s machine.

Add a database and sign-in, then go to production

A guided build that takes Harbor’s data from the session all the way to production.