No lock-in
Rocky compiles your models to ordinary SQL. rocky emit-sql hands you that SQL directly. If you ever step away from the engine, you keep runnable files rather than a proprietary format.
rocky emit-sql
Section titled “rocky emit-sql”rocky emit-sql renders the SQL each transformation model would produce. It needs no warehouse connection and it runs nothing:
# Print the SQL for every model to stdoutrocky emit-sql --models models/
# Write one <model>.sql file per modelrocky emit-sql --models models/ --out-dir build/sql/
# Just one modelrocky emit-sql --models models/ --model fct_ordersRocky generates that output through the same code path rocky run uses, including any declared surrogate-key columns. The SQL dialect comes from the target adapter configured in your rocky.toml: Databricks, Snowflake, BigQuery, Trino, or DuckDB. With no resolvable config, it defaults to DuckDB.
A full-refresh model emits a complete CREATE OR REPLACE TABLE … AS …. That statement runs as-is, and it matches what a run executes.
A merge or delete_insert model emits its steady-state statement instead, against an existing target. rocky run creates that target on the first build. A static SQL file cannot, so those files include a short note. Treat them as the recurring operation, not as a from-scratch build.
The export needs a project that compiles cleanly. A transformation model with type = "incremental" fails with E037 and stops the whole export.
Rocky emits models in dependency order: a model never appears before one it reads. The stdout form is therefore a single ordered script you can pipe straight to your warehouse:
rocky emit-sql --models models/ > build/all.sqlduckdb mart.db < build/all.sqlThe --out-dir form writes one <model>.sql per model, for inspection, editing, or dropping into dbt. To run those files directly, follow the same dependency order. rocky dag prints it:
rocky dag --models models/ # execution orderduckdb mart.db < build/sql/raw_orders.sqlduckdb mart.db < build/sql/fct_orders.sqlThe fallback recipe
Section titled “The fallback recipe”To stop depending on Rocky for a model, or for the whole project:
- Run
rocky emit-sql --models models/ --out-dir build/sql/to capture the SQL. - Run
rocky dag --models models/to capture the run order. - Run the files against your warehouse, or drop each
<model>.sqlinto a dbt model, a scheduled query, or a hand-maintained script. The SQL has no Rocky-specific syntax.
For full-refresh models this path is exact. A CI test emits the SQL and executes it directly against DuckDB, so the path stays runnable as the engine evolves rather than becoming documentation that quietly rots.
What it doesn’t cover
Section titled “What it doesn’t cover”emit-sql renders transformation models only.
Replication pipelines are incremental source-to-target copies driven by the engine’s watermark state. Their SQL preview lives behind the live rocky plan path instead.
Some models produce no standalone statement. Rocky reports those on stderr rather than dropping them silently. That happens when a strategy needs a live connection to render. A Snowflake dynamic table is one example: it resolves its compute-warehouse name at runtime.
Related
Section titled “Related”- SQL Generation — how Rocky compiles each strategy to the SQL that
emit-sqlrenders. - Model Format — the sidecar fields, including the
[[surrogate_key]]blockemit-sqlcarries through. - Migrating from dbt — uses
emit-sqlfor a connection-free side-by-side and as the exit door.