Skip to content

Releases: SQLAnvil/sqlanvil

v1.23.0 — Guided setup: `init --interactive` (and `init --bare`)

Choose a tag to compare

@ihistand ihistand released this 07 Jul 18:12
  • 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.json for 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 init is unchanged for scripts and CI, and
      --interactive fails fast with guidance when there's no terminal to talk 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

Choose a tag to compare

@ihistand ihistand released this 07 Jul 01:26
  • 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 plus migration-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 declared schema:
    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
    stays ods.zip_code, keeping schema-qualified ref()s working after a migration.
    Declarations without a schema: keep the previous <connection>_ext placement.
  • Empty columnTypes now compiles on runner-extract declarations (introspect them
    incrementally); the extract fails at run time — before touching or billing the source —
    with the exact sqlanvil introspect command to fix it. FDW-mode declarations still require
    columnTypes at 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`

Choose a tag to compare

@ihistand ihistand released this 06 Jul 17:39
  • sqlanvil init now 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 in intermediate/, output tables
    built from the staging layer (daily_sales, product_revenue, and orders_by_region
    joining both sources), and a business-rule assertion. compile is green out of the box
    on every warehouse; validate pinpoints exactly which sources
    still need wiring before run.
    • On Postgres/Supabase the BigQuery source rides a bigquery_public
      connection in mode: runner-extract — no Vault secret,
      no wrappers extension. 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, user postgres.<project-ref>) — the direct
      db.<ref>.supabase.co host is IPv6-only and unreachable from most networks.
    • Postgres/Supabase projects default defaultDataset to public; scaffold directories
      survive the first commit (.gitkeep); --warehouse mysql documented in init help.
  • Selective runs no longer execute unrelated extracts. run --actions/--tags previously
    ran every runner-extract source 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-deps still 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

Choose a tag to compare

@ihistand ihistand released this 06 Jul 02:38
  • 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 and s3:///gs:// URIs are unaffected.

Install: npm i -g @sqlanvil/cli@1.20.1

v1.20.0 — Python script actions

Choose a tag to compare

@ihistand ihistand released this 06 Jul 02:38
  • python: script actions — run Python file-staging and
    glue steps as first-class DAG nodes, declared in actions.yaml against a plain .py file.
    The ingestion slot Dataform/dbt leave outside the pipeline: download → import → staging →
    marts in one sqlanvil 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 that pythonVersion is 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 validate checks 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_NAME env,
      optional venv: interpreter, args:, exit 0 = success, 30-min default timeout
      (timeoutMillis overrides).
    • Language-neutral underneath (script: with a language field — python: is sugar), so
      future runtimes are additive.
    • The mailing_list example's
      OpenAddresses ingestion is now fully in-DAG: a python: action stages the CSV (bundled
      sample, or a real openaddresses.io download via the oa_source_url var) 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.

Install: npm i -g @sqlanvil/cli@1.20.0

v1.19.0 — The `mysql: {}` block is feature-complete

Choose a tag to compare

@ihistand ihistand released this 03 Jul 19:11
  • FULLTEXT / SPATIAL indexesindexes: [{ columns: ["title"], type: "fulltext" }]
    (mutually exclusive with unique; a spatial index needs a NOT NULL SRID geometry column,
    which usually means an ALTER TABLE … MODIFY in post_operations first).
  • Index prefix lengths — a column may carry MySQL's own prefix syntax, "body(50)"
    `body`(50) (required to index TEXT/BLOB columns).
  • rowFormat table option — emitted as ROW_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

Choose a tag to compare

@ihistand ihistand released this 03 Jul 18:39
  • MySQL/MariaDB cross-warehouse sources — a platform: mysql connection
    can now feed a Postgres/Supabase warehouse. Declare a source with connection: and SQLAnvil reads
    database.table at run time and materializes it as a plain ref()-able table — the same
    runner-extract mechanism as keyless BigQuery sources (capped at 1M rows / 512 MB). MySQL sources
    are runner-extract only (there is no Postgres FDW for MySQL); an explicit mode: fdw is a
    compile-time error. Source credentials (host, port, user, password) live in
    .df-credentials.json's connections map. Validated against MySQL 8 and MariaDB 11.
  • sqlanvil introspect maps MySQL types to Postgres types — scaffolded columnTypes from a MySQL
    source now arrive as warehouse-valid types (datetimetimestamp, doubledouble precision,
    jsonjsonb, 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

Choose a tag to compare

@ihistand ihistand released this 03 Jul 04:34
  • Fix: run --graph no longer requires the working directory to contain a workflow_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)

Choose a tag to compare

@ihistand ihistand released this 03 Jul 02:00
  • sqlanvil run --graph <file> — run the JSON emitted by compile --json directly, 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-run all apply to the loaded graph.
  • Guards: --environment with --graph is rejected (compile with --environment instead, and pass
    --credentials explicitly); --dry-run on Postgres/Supabase/MySQL is rejected (validate needs the
    project source). The CLI warns when the graph was compiled by a different core major.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

Choose a tag to compare

@ihistand ihistand released this 02 Jul 17:47
  • BigQuery column types: BIGNUMERIC, JSON, and INTERVAL source 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 .sql or
    Markdown snippet); paths are resolved relative to the calling file and confined to the project directory.
  • Assertion metadata — assertions accept a metadata block, carried through to the action descriptor.
  • actions.yaml guard — referencing a .sqlx file from actions.yaml now raises a clear error;
    .sqlx files are compiled directly from definitions/.
  • Internal: the build migrated to Bazel 7.3.2 + bzlmod (no user-facing change).

Install: npm i -g @sqlanvil/cli@1.16.0