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:| Variable | Description |
|---|---|
ctx | Dictionary of context variables from context.py |
source(source_name) | Macro that returns the table name for the referenced source |
ref(source_name) | Alias for source() |
is_placeholder(name) | Check if a placeholder exists |
ctx:
| Variable | Description |
|---|---|
proj_vars | Dictionary of project variables from squirrels.yml |
env_vars | Dictionary of environment variables |
user | The authenticated user object with username and custom_fields |
prms | Dictionary of parameter objects |
param_exists(param_name) | Check if a parameter exists and is enabled |
set_placeholder(name, value) | Register a parameterized query placeholder |
The source() macro
The source() macro (also available as ref()) is used to reference source models:
YAML configuration
The YAML configuration file specifies the database connection and other options:models/dbviews/dbv_transactions.yml
Configuration fields
A description of the model for documentation purposes.
The database connection to use. Must match a connection defined in
squirrels.yml or pyconfigs/connections.py. If not specified, uses the default connection.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 of source names this dbview depends on. Optional but recommended. Squirrels can derive this from
source() macro calls.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
Iftranslate_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
Thetranslate_to_duckdb option enables automatic SQL dialect translation:
- The SQL query is parsed using the source database’s dialect
- The query is translated to DuckDB SQL dialect using sqlglot
- The query runs on the VDL instead of the external database
- Source references resolve to VDL table names
- 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
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
: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
- Use descriptive names: Prefix dbview names with
dbv_to distinguish them from other model types. - 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_duckdbto run the query on DuckDB instead. - 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.
- Document conditional columns: If a specific column only exists based on parameter selections, use the
conditionfield to document it. - Use placeholders for user input: Always use placeholders (e.g.
:min_amount) for values that come from user text input to prevent SQL injection. - Mask sensitive data: Use conditional logic based on user fields to mask sensitive columns.
Related pages
- 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