Skip to main content
Dbview models are SQL queries that run directly on external databases at query time. Unlike build models which materialize data in the Virtual Data Lake (VDL), dbview models execute their queries on the original database connection, making them ideal for real-time data access. Dbview models are stored in the models/dbviews/ directory and can only be written in SQL (using the dialect of the target database).

File structure

SQL dbview models

Dbview models are written in the SQL dialect of the database connection they use (e.g., SQLite, PostgreSQL, MySQL).

Example dbview model

models/dbviews/dbv_transactions.sql

Available Jinja variables

The following variables are commonly used in dbview models: The following variables are also available in dbview models, but are less commonly used given the availability of ctx:

The source() macro

The source() macro (also available as ref()) is used to reference source models:
Dbview models can only reference sources - not seeds, build models, or other model types. Use federate models if you need to reference those.

YAML configuration

The YAML configuration file specifies the database connection and other options:
models/dbviews/dbv_transactions.yml

Configuration fields

string
default:""
A description of the model for documentation purposes.
string
default:"default"
The database connection to use. Must match a connection defined in squirrels.yml or pyconfigs/connections.py. If not specified, uses the default connection.
boolean
default:"false"
If true, the SQL query is translated from the source database’s dialect to DuckDB and executed on the VDL instead of the external database. See Query translation for details.
list[string]
default:"[]"
List of source names this dbview depends on. Optional but recommended. Squirrels can derive this from source() macro calls.
list[object]
default:"[]"
Column metadata definitions as a list.

Source referencing rules

Dbview models have specific rules for referencing sources:

Same connection required

A dbview model can only reference sources that share the same database connection. This is because dbview queries run directly on the external database.

translate_to_duckdb restriction

If translate_to_duckdb: true, the dbview can only reference sources with load_to_vdl: true. This is because the translated query runs on DuckDB using VDL data.

Query translation

The translate_to_duckdb option enables automatic SQL dialect translation:
When enabled:
  1. The SQL query is parsed using the source database’s dialect
  2. The query is translated to DuckDB SQL dialect using sqlglot
  3. The query runs on the VDL instead of the external database
  4. Source references resolve to VDL table names
The translation supports any SQL dialect that sqlglot supports, including PostgreSQL, MySQL, SQLite, Snowflake, BigQuery, Redshift, Spark, Trino, and many more. This is useful when:
  • You want the performance of running analytical queries on DuckDB instead of a transactional database
  • You want to reduce load on the external database
  • You prefer working with the SQL dialect of your external database
translate_to_duckdb is not allowed when the dbview’s connection type is DuckDB (as opposed to SQLAlchemy, ConnectorX, etc.). In this case, use a federate model instead.

Dynamic queries with parameters

Dbview models can use parameters and context variables to create dynamic queries:
models/dbviews/dbv_transactions.sql

Using placeholders for SQL injection prevention

For user-provided values, use placeholders to prevent SQL injection:
models/dbviews/dbv_transactions.sql
The :placeholder_name syntax when using a SQLAlchemy connection type (or $placeholder_name for DuckDB connection type) is used in the query for parameterized execution. The placeholder can be set using context variables in pyconfigs/context.py. For instance:
pyconfigs/context.py

Best practices

  1. Use descriptive names: Prefix dbview names with dbv_ to distinguish them from other model types.
  2. Be mindful of query performance: Dbview queries run on the external database in real-time. If the external database is not optimized for large-scale analytical queries, consider using translate_to_duckdb to run the query on DuckDB instead.
  3. Use translate_to_duckdb strategically: Enable this option to reduce load on production databases, but be aware that you’ll be querying potentially stale VDL data.
  4. Document conditional columns: If a specific column only exists based on parameter selections, use the condition field to document it. For example, if a column only exists when the group_by parameter is set to "Transaction", then the condition field should be set to ["group_by == 'Transaction'"].
  5. Use placeholders for user input: Always use placeholders (e.g. :min_amount) for values that come from user text input to prevent SQL injection.
  6. Mask sensitive data: Use conditional logic based on user fields to mask sensitive columns.
  • Sources - Configure source tables from external databases
  • Federate models - Dynamic models that run on DuckDB
  • Context variables - Set context variables that transforms parameter selections into meaningful values at runtime