feat(datatables): datatable migrations (GIT-890)#9495
Draft
diegoimbert wants to merge 6 commits into
Draft
Conversation
When a datatable is selected in the SQL REPL, detect schema-changing (DDL) statements (CREATE/ALTER/DROP/TRUNCATE/...) on run and surface a confirmation modal recommending that schema changes be recorded as migrations rather than run ad-hoc. The user can still proceed with "Run anyway". Non-datatable inputs and pure read/DML queries are unaffected. DDL detection is extracted into a small, unit-tested `sqlDdl.ts` helper. First stage of the datatable migrations feature (GIT-890). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying windmill with
|
| Latest commit: |
5856435
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://3fc7b62a.windmill.pages.dev |
| Branch Preview URL: | https://diego-git-890-datatable-migr.windmill.pages.dev |
Add a `datatable_migration` table storing versioned SQL scripts per datatable,
and a runner that applies pending migrations to the datatable's backing
Postgres database. Applied state is tracked inside that database in a
`_windmill_datatable_migrations` table, so it survives forks (the table is
copied with the rest of the database).
New workspaced API under /datatable_migrations/{datatable}:
- list — migrations + applied/drifted status (drifted = edited after apply)
- create — store a new migration (version auto-generated from timestamp)
- upsert — create-or-update by version (used by the CLI push)
- delete — remove a migration
- run — apply all not-yet-applied migrations in version order
Each migration runs in its own transaction together with its tracking insert.
Part of GIT-890.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The REPL's DDL warning modal now offers "Save as migration" as the primary action: it records the query as a datatable migration and applies pending migrations via the runner. "Run once without saving" remains as an escape hatch. The new endpoints are declared in openapi.yaml and consumed through the generated client. Remove the best-effort migration generation on fork: - create_workspace_fork no longer snapshots the parent datatable schema (forked_from is now just a marker object) - DatatableSchemaDiff (original/parent/fork three-way diff + generated ALTER/CREATE SQL) is replaced in CompareWorkspaces by DatatableMigrations, which lists each datatable's migrations with applied/pending/drifted status and a "Run pending migrations" action. Applied state lives inside the datatable database itself, so it survives forks. Part of GIT-890. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Datatable migrations now round-trip through git as plain SQL files under
_datatable_migrations/{datatable}/{version}_{name}.sql:
- The workspace tarball export includes them, so `wmill sync pull` writes
them to disk (identifiers that are not file-path safe are skipped with a
warning rather than producing unparseable filenames).
- `wmill sync push` upserts added/edited files by version and deletes
removed ones. They are excluded from the script push path and from
lockfile metadata generation (plain .sql is not a script language).
- After a push that touches migration files, pending migrations are applied
to each affected datatable — so merging new migration files into a
git-synced branch runs them on the target workspace.
- Pushing an edit to an already-applied migration logs a warning that the
new content will NOT be re-run (drift detection). Checksums ignore
trailing whitespace so editor-appended final newlines don't count as
drift.
Part of GIT-890.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Forked workspaces now receive a copy of the parent's datatable migration scripts. Applied state is tracked inside the datatable database itself, so a fork that copies the database sees the same migrations as applied; migrations added to the parent afterwards reach the fork via sync and are applied by the migration runner. Part of GIT-890. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements datatable migrations (Fixes GIT-890): schema changes to datatables are recorded as versioned SQL migration scripts that are tracked per datatable, synced to git as plain
.sqlfiles, applied by a migration runner, and carried across workspace forks — replacing the previous best-effort schema-diff generation on fork.How it works
Storage & runner (backend)
datatable_migrationtable: versioned SQL scripts per(workspace, datatable)with name, content, checksum._windmill_datatable_migrationstable (like sqlx/flyway). Since a fork copies the database, the fork automatically sees the same migrations as applied — no state reconstruction needed./datatable_migrations/{datatable}:list(withapplied/driftedstatus),create,upsert,delete,run— declared inopenapi.yaml, consumed via generated clients (frontend + CLI).REPL warning modal (frontend)
CREATE/ALTER/DROP/TRUNCATE/…) against a datatable in the SQL REPL surfaces a "Schema change detected" modal.sqlDdl.tshelper (leading-verb match only —SELECT 'create table'is not flagged).CLI sync (
_datatable_migrations/folder)_datatable_migrations/{datatable}/{version}_{name}.sql.wmill sync pullwrites them from the workspace tarball export;wmill sync pushupserts added/edited files by version and deletes removed ones..sqlis not a script language).Fork behavior (replaces best-effort diff)
create_workspace_forkno longer snapshots the parent datatable schema; theDatatableSchemaDiffthree-way diff + generated ALTER/CREATE SQL component is removed.Edit-after-apply warning (secondary requirement)
drifted). The UI shows an "edited after apply" badge (visible in the screenshot above), andwmill sync pushlogs a warning that the edited content will NOT be re-run. Checksums ignore trailing whitespace so editor-appended final newlines don't count as drift.Validation
cargo check(windmill-api, windmill-api-workspaces) — clean;SQLX_OFFLINE=truebuild passes (cache updated via the safe procedure, zero EE-cache deletions).npm run check— 0 errors;vitestsqlDdl tests pass; svelte-autofixer applied (keyed each blocks).bun testunit suite — 815/815 pass (incl. new path-parsing tests);tscintroduces no new errors (pre-existing baseline verified by stash-diff).CREATE TABLE→ modal → "Save as migration" → migration stored, runner applied it, tracking row written; "Run once without saving" executes without recording;SELECTunaffected.sync pullwrites the.sqlfile; adding a file +sync pushupserts and auto-applies it (table created); deleting the file + push removes the remote migration; editing an applied migration + push logs the drift warning; re-push after workspace-side row loss correctly reports "no pending migrations" (applied state survives in the datatable DB).Notes
_windmill_datatable_migrationstracking table is visible in the DB manager like any other table (same as flyway/sqlx conventions).DataTableForkedFrom.schemais kept as a legacy optional field so existing settings JSON still round-trips; it is no longer written.create/upsert/delete/runrequire workspace admin.🤖 Generated with Claude Code