← All Releases

v0.2.52

LATEST2026-08-23

THE RING, COMPLETE

The ring closed. Every one of the 110 engine-to-engine transitions among DVT's eleven live engines — Postgres, MySQL, MariaDB, MySQL 5.7, SQL Server, Oracle, ClickHouse, Trino, DuckDB, Snowflake and Databricks — is now proven green in both directions, each under the same 27-command battery against real databases: flip, parse, seed, build twice, snapshot twice, idempotence, row counts and named values against canonical truth, docs, sources, metadata, base views, a native statement, a zero-residual retract, a landed branch. The second half of the walk crossed into the clouds, and the clouds fought back: warehouses that suspend themselves mid-build, connectors that declare one type and write another, transpiler artifacts that are load-bearing on one engine and fatal on the next, and a whole family of diseases that only wake on an engine's second or third visit — which is precisely what an exhaustive walk exists to force. Every fix below carries the hop that found it.

FIXED

  • Retract now drops every spelling an engine can hold. Sling creates quoted-preserving-case, the native phase creates unquoted-upfolded, and one Snowflake table survived a green retract wearing mixed per-part case — the drop now enumerates the spellings instead of assuming one.
  • Sling's staging on Snowflake is branded: DVT ensures and uses an internal stage named DVT_STAGING on every auth method — password, key-pair and OAuth alike — instead of the connector's default name.
  • Columns with spaces or special characters land on Databricks. Delta refused the CREATE outright, and the connector's CSV volume lane rendered a spaced name as an empty identifier; every Databricks load now rides the parquet volume lane under a column-mapping table definition, so the names you have are the names that land.
  • Decimals and timestamps land on Databricks with the types the loader actually writes. The connector declared decimal(2,1) then wrote decimal(24,6), declared timestamp_ntz then wrote tz-aware micros — Delta refuses to merge either mismatch, so DVT now pins both to what the writer ships.
  • Snowflake and Databricks join the keyless-watermark allow-set — measured, not assumed, on live accounts: a first run that creates and moves exactly its rows, a second run handed the same data plus one new row that moves exactly one. Engines that fail that receipt stay refused by name.
  • Update-key-only incrementals work fully qualified on Snowflake, whose connection URL carries no session database: seed objects, schema creation, catalog queries and retract drops all address database.schema.name explicitly now.
  • A federated hook's {{ this }} renders exactly where the loader landed the relation — on schemaless engines it had been rendering a schema the relation never had.
  • SQLite is scoped honestly: a source to extract from and a custom write target, never a default-target warehouse. Its 24 default-target transitions are parked by ruling, and reads and writes are proven in every remaining hop.
  • Sling crashes retry instead of failing your build. A SIGSEGV, a Go panic, and Oracle's SQL*Loader racing itself over /dev/stdin are each one bounded retry on a named list — real load errors still surface on the first try, because those reproduce.
  • Cloud warehouses that auto-suspend no longer fail loads and extractions caught in their wake-up window: operations against a cloud target or source retry on a warehouse clock, 60 then 120 seconds, after the quick retry misses.
  • ANSI FETCH FIRST becomes LIMIT on ClickHouse, which parses the clause and then refuses it at runtime without ORDER BY — the one transpiler gap the flip could not see because the SQL was syntactically valid.
  • The T-SQL dummy ORDER BY (SELECT NULL) — genuinely required on SQL Server for OFFSET/FETCH — is stripped at Oracle's door, where a scalar-subquery ORDER BY dies with ORA-00923. Real orderings are untouched.
  • Trino objects are addressed downfolded, matching how its catalogs actually store schemas: a mixed-case schema no longer collides with its own lowercase survivor on the second visit through the direct lane.
  • A whole-project retract now clears ALL local incremental bookkeeping, including state whose model never made the ledger. A stale {{ this }} index had let a model compile as incremental against a target that did not exist, land nothing, and report green on zero rows.
  • Models that read another model's output through a source() declaration can declare the dependency explicitly — the sample project's own reader raced its producer on a clean workspace until the edge was made real.
  • dvt sync provisions bulk accelerators on Linux as well as macOS, and a missing accelerator is a warning with install guidance, never a failed sync.
  • The dbt-labs upstream remnants are gone from both packages — DVT is a separate product, and its repositories, docs and metadata now say so everywhere.

ADDED

  • dvt init scaffolds a project whose first dvt build runs green immediately — model and seed, DuckDB default, no warehouse, no prompts.
  • The hub's Settings pages were driven end-to-end in a real browser: the Connections setter validates, creates scoped to one profile with timestamped backups, and its Test Connections proves BOTH lanes per connection — the transformation adapter and the federation loader. The AI Credentials page stores keys write-only, displays them masked, and its TEST performs a live gateway roundtrip.
  • Catalog, API Portal, Explorer, Profiling, Scheduler, Dashboards, Executions and Chat with Martin all verified against a fresh project — the Explorer's click-to-query computes on the engine, and Executions shows every run with per-phase timing.

Get it: pip install dvt-core==0.2.52 · wheels on PyPI for macOS (arm64 + x86_64) and Linux x86_64, Python 3.10–3.14 — the full platform matrix.