Skip to content

Create table, alter table - APIs and modals#2789

Open
simonw wants to merge 18 commits into
mainfrom
codex/alter-table-modal
Open

Create table, alter table - APIs and modals#2789
simonw wants to merge 18 commits into
mainfrom
codex/alter-table-modal

Conversation

@simonw

@simonw simonw commented Jun 17, 2026

Copy link
Copy Markdown
Owner

simonw added 5 commits June 16, 2026 17:33
Previously there were four lines of whitespace, but that
meant users had to delete that whitespace themselves when
they started editing. Now it is four lines tall without that.
Adds a permission-gated database action that opens a create table modal on database pages, backed by the existing create-table JSON API.

The modal starts with an id integer primary key column plus a blank text column, supports SQLite type selection, and shows custom column type controls only when the actor can set column types.

Selected custom column types are applied after table creation with follow-up set-column-type API calls. Includes styling plus HTML and Playwright coverage for the action payload and create-table flow.
- Add POST /<database>/<table>/-/alter with Pydantic validation and dry-run support.
- Support add, rename, alter, drop, primary-key and reorder operations, including allow-listed default expressions.
- Document the endpoint and cover schema changes, validation, permissions, events and dry runs.

Refs #2788
- Register a built-in table action and expose alter-table metadata to table pages.
- Build the client-side modal for editing columns, defaults, ordering, primary keys, and custom column types.
- Add a review/apply confirmation flow with HTML and Playwright coverage.

Refs #2788
Comment thread datasette/static/app.css
Comment on lines +1752 to +1776
dialog.table-create-dialog {
--ink: #0f0f0f;
--paper: #eef6ff;
--muted: #6b6b6b;
--rule: #d8e6f5;
--accent: #1a56db;
--card: #ffffff;
border: none;
border-radius: var(--modal-border-radius, 0.75rem);
padding: 0;
margin: auto;
width: min(760px, calc(100vw - 32px));
max-width: 95vw;
max-height: min(780px, calc(100vh - 32px));
box-shadow: var(--modal-shadow, 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04));
animation: datasette-modal-slide-in var(--modal-animation-duration, 0.2s) ease-out;
overflow: hidden;
font-family: system-ui, -apple-system, sans-serif;
background: var(--card);
}

dialog.table-create-dialog[open] {
display: flex;
flex-direction: column;
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is consistent with our other dialogs but there's a whole lot of duplicate model code now. Filing an issue to clean that up later:

simonw added 2 commits June 17, 2026 09:59
- Use a per-process socket path for the UDS test fixture.
- Clean up stale socket files before and after the fixture runs.
- Close the HTTP client and wait for the Datasette subprocess to exit.
- Extract reusable helpers for database and table action permission preloading.
- Precompute those permissions before building table-page HTML data.
- Document the default table actions plugin.
@simonw

simonw commented Jun 17, 2026

Copy link
Copy Markdown
Owner Author

Pyodide tests are failing with:

ValueError: Couldn't find a pure Python 3 wheel for 'pydantic-core==2.46.4'. You can use micropip.install(..., keep_going=True) to get a list of all packages with missing wheels.

That shouldn't be an issue now, see: https://simonwillison.net/2026/Jun/13/publishing-wasm-wheels/

Might need to upgrade Pyodide (here and in Datasette Lite).

@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 658 lines in your changes missing coverage. Please review.
✅ Project coverage is 0.00%. Comparing base (1ae5500) to head (1014880).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
datasette/views/table_create_alter.py 0.00% 597 Missing ⚠️
datasette/views/table.py 0.00% 31 Missing ⚠️
datasette/default_table_actions.py 0.00% 12 Missing ⚠️
datasette/views/database.py 0.00% 7 Missing ⚠️
datasette/views/table_extras.py 0.00% 6 Missing ⚠️
datasette/app.py 0.00% 5 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff           @@
##            main   #2789    +/-   ##
======================================
  Coverage   0.00%   0.00%            
======================================
  Files         70      72     +2     
  Lines      11173   11702   +529     
======================================
- Misses     11173   11702   +529     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Now that we depend on pydantic we need a more recent
pyodide in order to load the emscripten build
of pydantic-core.

Refs #2789 (comment)
@simonw

simonw commented Jun 17, 2026

Copy link
Copy Markdown
Owner Author

There's a feature missing from both create and alter: foreign key constraints. These are worth supporting, particularly since the edit/insert modals have neat support for them.

Related to that: setting the "label column" for a table. Might need a larger issue for that since we need to store label columns somewhere, probably in the same place as custom column types.

- Move create-table and alter-table API views into table_create_alter.py.
- Keep create and alter schema-editing constants and helpers together.
- Rename the create table modal context helper.
@simonw simonw marked this pull request as ready for review June 17, 2026 18:37
simonw added 2 commits June 17, 2026 12:38
- Add fk_table and optional fk_column support to create-table columns.
- Validate create-table requests with Pydantic while preserving existing errors.
- Document the API and cover inferred primary-key and validation cases.
Refs #2789 (comment)
- Add add_foreign_key, drop_foreign_key, and set_foreign_keys operations.
- Validate flat fk_table and fk_column arguments with Pydantic.
- Document the API and cover inferred primary-key and validation cases.
@simonw simonw force-pushed the codex/alter-table-modal branch from 2930f7a to fbab41f Compare June 17, 2026 21:03
simonw added 7 commits June 17, 2026 14:47
Improved version of the implementation datasette-edit-schema
Returns a list of tables with a single primary key, and for each one
the name of that primary key column and its SQLite type affinity.

This will be used by the create table UI to suggest foreign keys.
- Add foreignKeyTargetsPath to create table page data
- Filter hidden tables from database-level foreign key target results
- Update JSON API docs and tests for filtered targets
- Add create table advanced controls for foreign keys and first-column primary keys
- Share schema dialog row helpers between create and alter dialogs
- Move custom type into advanced options and add Add column icons
In the create table dialog a column can now have either a custom display
type or a foreign key target, but not both - a foreign key column's type
is determined by the referenced primary key, so a custom type doesn't
apply. Setting one clears and disables the other, and the foreign key
select stays disabled on the primary key column and when no targets exist.

Also add "Controls how Datasette displays and edits this column" help
text (with aria-describedby) under the custom type selector in both the
create and alter dialogs, and style the alter dialog help text.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant