Skip to content

Edit, add and delete rows

A value in one row is wrong, and you want to put it right without writing an UPDATE by hand. Alcuin stages every edit, shows you the SQL it will run, and writes nothing until you commit.

  1. Open the table and go to its Data tab. Find the row and filter to it if the table is large.
  2. Double-click a cell in the row. The row panel opens beside the grid.
  3. Double-click the field you want to change, or select it and press Enter. Type the new value.
  4. Click Set. In a one-line field, Enter does the same.

The edit is now a staged change. The field shows the new value with was and the old one under it, the grid marks the cell, and the table’s tab gets a dot. A bar rises under the grid:

1 change not saved yet · 1 edit

Double-click a cell, then the field in the row panel, type, and choose Set.

The notes table with one staged edit. The body cell of row 2 is outlined and reads Book the dentist for Tuesday, the row panel shows the new text with was and the old text under it, the notes tab has a dot, and the bar under the rows reads 1 change not saved yet · 1 edit, with Discard changes, Review SQL and Commit 1 row change.

A staged edit: four marks say it, and nothing has reached the database.

  1. The tab title has a dot.
  2. The cell is outlined.
  3. The field shows the new value, and the old one under it.
  4. The bar counts the staged changes.

You can also edit in the grid itself: select a cell, then press Enter or start typing. On a foreign key cell, Enter goes to the row it points to, so start typing instead. JSON and binary values open their editor in the row panel.

To clear a value, open the field’s menu and choose Set NULL.

  1. Open the command palette with ⌘⇧P on macOS, Ctrl+Shift+P on Windows and Linux.
  2. Run Insert row.
  3. The row panel opens on a New row. Every field reads DEFAULT until you set it.

Only the fields you set go into the INSERT. A field you leave alone gets the column’s default from the server. To send NULL on purpose, choose Set NULL from the field’s menu; Use the default puts it back.

Open the row panel’s Row actions menu and choose Delete row. You can also right-click a cell, or the row’s number, and choose Delete row. The panel says This row is marked for deletion. Nothing is deleted yet.

Click Review SQL in the bar. The review lists each change with its old and new values, and shows the SQL that will run beside them:

BEGIN;
UPDATE public.orders
SET note = 'Ring twice'
WHERE id = '48212'
AND xmin = '1001'::xid;
DELETE FROM public.orders
WHERE id = '48213'
AND xmin = '1000'::xid;
INSERT INTO public.orders (status)
VALUES ('pending');
COMMIT;
The review of three changes to orders: Update id 48212 with note changed from Leave at side door to Ring twice, Delete id 48213 with the row's values and the warning also deletes 1 row in shipments, and an insert of a new row with status pending. Each has a selected checkbox. On the right, under SQL that will run, is the transaction from BEGIN to COMMIT, with a Copy button.

The review of an edit, a delete and a new row, with the SQL that will run.

  1. Clear a checkbox to leave that change staged.
  2. A deleted row that other rows point at is flagged under its change.
  3. Copy the SQL.

Some things to know when you read it:

  • Every change runs in one transaction. If any of it fails, none of it lands.
  • Each UPDATE and DELETE finds its row by the table’s primary key, and by xmin, the version of the row you loaded. A table with no primary key is matched by its smallest unique index instead: the one with the fewest columns, valid, with no expression and no WHERE, whose columns are all NOT NULL or which is NULLS NOT DISTINCT. If anyone changed the row since, the statement matches nothing and Alcuin commits nothing. See A row changed under you below.
  • Values are sent to the server separately from the statement. They are written inline here so you can read them.
  • A deleted row that other rows point at is flagged under its change, for example also deletes 1 row in public.shipments for a cascade, or blocked: 3 rows in public.order_items still point to it.
  • Generated columns, and identity columns the server always sets, are left out, and the review says so.

Clear a change’s checkbox to leave it staged and commit the rest. Copy the SQL with the copy button beside SQL that will run.

In the review, click the Commit button, such as Commit 3 changes. From the bar, click Commit 3 row changes. Or press ⌘S on macOS, Ctrl+S on Windows and Linux.

When it lands, the bar goes, the dot on the tab clears, and the grid reads the rows again so you see them as the server has them now.

On a production connection that is still read-only, committing asks whether to apply it once. A commit that deletes rows asks first too, as a destructive change. See Work on production without breaking it.

To drop a change you staged, right-click a cell in its row and choose Undo changes to this row. For a new row, the row panel’s Row actions menu offers Discard this row.

To drop everything, click Discard changes in the bar, or Discard all changes in the review. Alcuin asks first, naming what goes, for example This drops 2 row changes staged on orders. Nothing has run, so there is nothing to undo on the server.

Staged changes survive a quit or a crash. Open the table again and the bar says restored from your last session.

If someone changed or deleted a row after you loaded it, the commit stops before anything lands, and the bar says:

A row changed under you.

Your other changes stay staged.

Review the stale row, then Keep mine.

  1. Click Review the stale row. The review reads the row as it is on the server now, and names the columns that changed, for example Changed on the server: status, updated_at.
  2. Choose Keep mine to write only the columns you edited over the current row, or Take theirs to drop your edit.
  3. Commit.

To drop every stale change at once and read the rows again, click Discard stale and reload. ALC-3002: Row changed since you loaded it has the details, including when the server skipped a statement on purpose.

The grid shows your new value with no mark on it, the bar is gone, and the tab has no dot. The change is in the database.

  • Rows here are read-only. with No primary key or unique index, so rows cannot be matched safely. Edit with a query. means Alcuin has no safe way to find one row. Select the row and click Open as query for a draft UPDATE in a query tab. It matches every row with exactly those values, so check the count before you run it.
  • This update would have changed 2 rows, not one, so nothing was changed. means the key and row version matched more than one row, usually because another table inherits from this one and holds a row with the same key. Nothing was written. Edit those rows with a query that names the table you mean, such as UPDATE ONLY public.orders ….
  • No editing at all, and no Delete row in the menu, most often means the connection is read-only. See ALC-3001: Connection is read-only. Editing is also off while the connection is lost, while you view the table as another role, or when your role may not change the table.
  • Another transaction holds a lock these changes need, so nothing was changed. means another session, often your own query tab with a transaction open, is holding up the change. Commit or roll back there, then commit again.
  • If the reply to a commit was lost, Alcuin settles it before trying again, so a change never applies twice. See ALC-1005: Transaction outcome unknown and ALC-3003: Changes already applied.