Virtual environments require two things:Documentation Index
Fetch the complete documentation index at: https://docs.sqlbuild.com/llms.txt
Use this file to discover all available pages before exploring further.
environment_mode = "virtual" in your project config, and a state store configured for your active environment.
Project configuration
environment_mode field switches the project from direct mode (default) to virtual mode. All state, plan, build, promote, rollback, and reconcile commands route through the virtual path when this is set.
State configuration
Each physical environment that uses virtual mode needs a[environments.<name>.state] block:
| Field | Required | Description |
|---|---|---|
backend | Yes | State store engine: duckdb or postgres |
schema | Yes | Schema name for state tables |
connection | Yes | Backend-specific connection config |
allow_reset | No | Whether sqb state reset is permitted (default: false) |
unsuffixed_virtual_env | No | VDE name that uses the base schema without a suffix (for adopt/detach) |
DuckDB state backend
Postgres state backend
State initialization
Before using virtual commands, initialize the state store:State lifecycle
| Command | Description |
|---|---|
sqb state init | Create state tables |
sqb state migrate | Back up current state and re-initialize tables |
sqb state rollback | Restore from the latest backup |
sqb state rollback --backup-id <id> | Restore from a specific backup |
sqb state reset --auto-approve | Drop all state tables (requires allow_reset = true) |
state migrate creates a backup schema (e.g. sqlbuild_state__backup_<id>) before re-initializing. This lets you roll back if a migration causes problems.
state reset is destructive and requires both allow_reset = true in config and --auto-approve on the command line.
Local overrides
Usesqlbuild_local.toml to override state connection config per developer:
Per-environment state
Different physical environments can use different state backends:Unsuffixed VDE naming
By default, all VDE logical views use a suffixed schema:dev__kevin.fact_orders. For the primary VDE that consumers query directly (e.g. the production VDE), you typically want clean unsuffixed names: dev.fact_orders.
Configure this with unsuffixed_virtual_env:
dev uses dev.fact_orders while other VDEs like kevin use dev__kevin.fact_orders.
This setting is also required for adopt and detach operations so that existing consumer queries continue to work after migrating to virtual mode.
Janitor configuration
When using virtual environments, configure the janitor to run periodically to clean up expired VDEs, old checkpoints, and unreferenced physical versions:State tables
The state store contains current-state tables and append-only history tables. You do not need to interact with these directly, but understanding what is stored helps when debugging: Current state:state_versions, model_versions, function_versions, physical_relations, physical_relation_ancestry, virtual_environments, virtual_environment_refs, virtual_environment_function_refs, virtual_environment_checkpoints, virtual_environment_checkpoint_refs, virtual_environment_checkpoint_function_refs, locks, state_operations
History: plan_runs, virtual_environment_ref_events, reconcile_events, state_migration_events, state_operation_events
