Releases: SQLAnvil/sqlanvil
Releases · SQLAnvil/sqlanvil
Release list
v1.23.0 — Guided setup: `init --interactive` (and `init --bare`)
sqlanvil init --interactive— a guided Q&A for starting a
project. First question: start fresh, or convert an existing Dataform project?- The fresh path walks warehouse choice, project directory, default schema, whether to
include the sample project (and its cross-warehouse BigQuery source), then a
credentials Q&A that writes the gitignored.df-credentials.jsonfor you — Supabase
defaults to the Session-pooler shape and warns if you paste the IPv6-only direct
db.<ref>host. It ends with your numbered next steps (compile,validate). - The convert path runs
migrate-dataform(source stays
read-only), then offers the same credentials Q&A and points you at the migration report. - Explicit flag only — plain
sqlanvil initis unchanged for scripts and CI, and
--interactivefails fast with guidance when there's no terminal to talk to.
- The fresh path walks warehouse choice, project directory, default schema, whether to
sqlanvil init --bare— scaffold the directory structure and config only, skipping the
sample project files. For when you're about to write (or generate) your own models.
Install: npm i -g @sqlanvil/cli@1.23.0
v1.22.0 — Migrate from Dataform
sqlanvil migrate-dataform <srcDir> <outDir>— convert
a Dataform/BigQuery project into a SQLAnvil-on-Postgres project. The source directory is
read-only; the output gets a converted project plusmigration-report.{md,json}.
Declarations stay in BigQuery as named runner-extract connections
(one per source GCP project); target SQL gets safe lexical rewrites plus inline
SQLANVIL-MIGRATE:markers on everything needing dialect review; credentials in the source
are never copied. Proven against a 1,404-file production project: 745 declarations → 6
connections, zero compile errors on the converted output.- Runner-extract declarations:
schema:now does the whole job. A declaredschema:
overrides the connection's dataset (so one connection per source project serves many
datasets) and names the Postgres schema the extract materializes into —ods.zip_code
staysods.zip_code, keeping schema-qualifiedref()s working after a migration.
Declarations without aschema:keep the previous<connection>_extplacement. - Empty
columnTypesnow compiles on runner-extract declarations (introspect them
incrementally); the extract fails at run time — before touching or billing the source —
with the exactsqlanvil introspectcommand to fix it. FDW-mode declarations still require
columnTypesat compile (a foreign table can't exist without its columns).
Install: npm i -g @sqlanvil/cli@1.22.0
v1.21.0 — A real starter project from `sqlanvil init`
sqlanvil initnow generates a working sample project in the shape real ones take:
source declarations (app_orders— a table your app already has — plus Google's public
ZIP data from BigQuery), staging views over them inintermediate/, output tables
built from the staging layer (daily_sales,product_revenue, andorders_by_region
joining both sources), and a business-rule assertion.compileis green out of the box
on every warehouse;validatepinpoints exactly which sources
still need wiring beforerun.- On Postgres/Supabase the BigQuery source rides a
bigquery_public
connection inmode: runner-extract— no Vault secret,
nowrappersextension. On BigQuery it's a native declaration; MySQL skips it
(cross-warehouse connections need a Postgres-family warehouse). - The Supabase credentials template now points at the Session pooler
(aws-1-<region>.pooler.supabase.com, userpostgres.<project-ref>) — the direct
db.<ref>.supabase.cohost is IPv6-only and unreachable from most networks. - Postgres/Supabase projects default
defaultDatasettopublic; scaffold directories
survive the first commit (.gitkeep);--warehouse mysqldocumented ininithelp.
- On Postgres/Supabase the BigQuery source rides a
- Selective runs no longer execute unrelated extracts.
run --actions/--tagspreviously
ran everyrunner-extractsource in the project regardless of selection — re-reading (and
re-billing) sources nothing selected depended on, and failing runs that never touched them.
Extracts now prune like every other action;--include-depsstill pulls one in when a
selected model reads it, and unselective runs are unchanged.
Install: npm i -g @sqlanvil/cli@1.21.0
v1.20.1 — Relative import/export paths are project-relative
- Fix: a relative local
location:on imports/exports
now resolves against the project directory, not the CLI's own working directory. Previously
sqlanvil run <projectDir>from anywhere else couldn't find files a
script action had just staged (scripts run with cwd = project
dir); the two now always agree. Absolute paths ands3:///gs://URIs are unaffected.
Install: npm i -g @sqlanvil/cli@1.20.1
v1.20.0 — Python script actions
python:script actions — run Python file-staging and
glue steps as first-class DAG nodes, declared inactions.yamlagainst a plain.pyfile.
The ingestion slot Dataform/dbt leave outside the pipeline: download →import→ staging →
marts in onesqlanvil run, ordered by dependencies and covered by run history.- Execution-time only — compile never runs Python (compiles stay hermetic and
deterministic). Compile checks config shape, file existence, and thatpythonVersionis a
well-formed specifier. - No warehouse credentials injected — scripts stage files;
type: "import"is the loading boundary. - You own the environment; SQLAnvil validates it —
sqlanvil validatechecks the interpreter against
pythonVersion,requirements:against the installed packages (offline, nothing is
installed), and the script's syntax — without executing it. Failures block dependents,
like models. - Contract: cwd = project dir,
SA_VARS(your vars as JSON) +SA_ACTION_NAMEenv,
optionalvenv:interpreter,args:, exit 0 = success, 30-min default timeout
(timeoutMillisoverrides). - Language-neutral underneath (
script:with alanguagefield —python:is sugar), so
future runtimes are additive. - The mailing_list example's
OpenAddresses ingestion is now fully in-DAG: apython:action stages the CSV (bundled
sample, or a real openaddresses.io download via theoa_source_urlvar) and the import
depends on it. - SQLAnvil Cloud: hosted runs reject script actions at compile time (like local file
paths) — user code doesn't execute on the shared runner. Local CLI and your own CI both
run them today.
- Execution-time only — compile never runs Python (compiles stay hermetic and
Install: npm i -g @sqlanvil/cli@1.20.0
v1.19.0 — The `mysql: {}` block is feature-complete
FULLTEXT/SPATIALindexes —indexes: [{ columns: ["title"], type: "fulltext" }]
(mutually exclusive withunique; a spatial index needs aNOT NULLSRID geometry column,
which usually means anALTER TABLE … MODIFYinpost_operationsfirst).- Index prefix lengths — a column may carry MySQL's own prefix syntax,
"body(50)"→
`body`(50)(required to indexTEXT/BLOBcolumns). rowFormattable option — emitted asROW_FORMAT=(e.g.DYNAMIC,COMPRESSED).- Fix: the
mysql: {}block on a materialized view (type: "view", materialized: true) now
compiles through — earlier versions silently ignored it there, despite the docs showing it. - With these, the
mysql: {}block covers table options, all index forms,
and partitioning — closing issue #35.
Install: npm i -g @sqlanvil/cli@1.19.0
v1.18.0 — MySQL/MariaDB as a read-only source
- MySQL/MariaDB cross-warehouse sources — a
platform: mysqlconnection
can now feed a Postgres/Supabase warehouse. Declare a source withconnection:and SQLAnvil reads
database.tableat run time and materializes it as a plainref()-able table — the same
runner-extractmechanism as keyless BigQuery sources (capped at 1M rows / 512 MB). MySQL sources
are runner-extract only (there is no Postgres FDW for MySQL); an explicitmode: fdwis a
compile-time error. Source credentials (host,port,user,password) live in
.df-credentials.json'sconnectionsmap. Validated against MySQL 8 and MariaDB 11. sqlanvil introspectmaps MySQL types to Postgres types — scaffoldedcolumnTypesfrom a MySQL
source now arrive as warehouse-valid types (datetime→timestamp,double→double precision,
json→jsonb, blobs →bytea, …), since they define the extract table's columns in the warehouse.- Fix: re-running an extract over an existing plain table no longer fails on the leftover
drop foreign table(drops are now relation-kind-aware; this affected BigQuery extracts too). - Fix: an explicit
schema:on a connection'd declaration was silently ignored — both the FDW
foreign-table bridge and extracts now honor it as the source schema/database.
Install: npm i -g @sqlanvil/cli@1.18.0
v1.17.1 — `run --graph` works from any directory
- Fix:
run --graphno longer requires the working directory to contain aworkflow_settings.yaml—
with a stored graph, the directory is only used for credentials and artifacts, so a bare directory
works (as the 1.17.0 notes intended).
Install: npm i -g @sqlanvil/cli@1.17.1
v1.17.0 — `run --graph` (execute a stored compiled graph)
sqlanvil run --graph <file>— run the JSON emitted bycompile --jsondirectly, without
compiling the project. What executes is exactly what was compiled — environment overrides are baked
in at compile time — which makes a stored graph a true release artifact: compile once, run the
same graph unchanged later or elsewhere. Selection flags (--actions,--tags,--include-deps,
--include-dependents),--full-refresh, and BigQuery--dry-runall apply to the loaded graph.- Guards:
--environmentwith--graphis rejected (compile with--environmentinstead, and pass
--credentialsexplicitly);--dry-runon Postgres/Supabase/MySQL is rejected (validateneeds the
project source). The CLI warns when the graph was compiled by a different coremajor.minor. - This powers pinned releases in SQLAnvil Cloud: scheduled workflow runs
can execute the exact stored snapshot a release captured.
Install: npm i -g @sqlanvil/cli@1.17.0
v1.16.0 — Synced to upstream Dataform 3.0.61
- BigQuery column types:
BIGNUMERIC,JSON, andINTERVALsource columns now map correctly
(to numeric/string) when reading table schemas. getContents(path)— read a file's raw contents inside a compilation (e.g. inline a.sqlor
Markdown snippet); paths are resolved relative to the calling file and confined to the project directory.- Assertion
metadata— assertions accept ametadatablock, carried through to the action descriptor. actions.yamlguard — referencing a.sqlxfile fromactions.yamlnow raises a clear error;
.sqlxfiles are compiled directly fromdefinitions/.- Internal: the build migrated to Bazel 7.3.2 + bzlmod (no user-facing change).
Install: npm i -g @sqlanvil/cli@1.16.0