Jinja is the game changing feature of dbt Core that allows us to create dynamic SQL code. In addition to the standard Jinja library, dbt Core includes additional functions and variables to make working with dbt even more powerful out of the box.
See our original post, The Ultimate dbt Jinja Cheat Sheet, to get started with Jinja fundamentals like syntax, variable assignment, looping and more. Then dive into the information below which covers Jinja additions added by dbt Core.
This cheatsheet references the extra functions, macros, filters, variables and context methods that are specific to dbt Core.
Enjoy!
dbt Core: Functions
These pre-defined dbt Jinja functions are essential to the dbt workflow by allowing you to reference models and sources, write documentation, print, write to the log and more.
dbt Core: Macros
These macros are provided in dbt Core to improve the dbt workflow.
dbt Core: Filters
These dbt Jinja filters are used to modify data types.
dbt Core: Project context variables
These dbt core "variables" such as config, target, source, and others contain values that provide contextual information about your dbt project and configuration settings. They are typically used for accessing and customizing the behavior of your dbt models based on project-specific and environment-specific information.
dbt Core: Run context variables
These special variables provide information about the current context in which your dbt code is running, such as the model, schema, or project name.
dbt Core: Context methods
These methods allow you to retrieve information about models, columns, or other elements of your project.
Please contact us with any errors or suggestions.
FAQ
What are config.meta_get and config.meta_requre how do they differ from config.get() differ from config.require()?
Starting with dbt 1.10, custom keys must be nested below the meta dictionary. In order to retreive these values, you must use config.meta_get('key', default='value') to fetch a meta dictionary config value and it can optionally return a default if it is not set. config.meta_require('key') strictly requires the config meta key to exist and throws a compilation error if it is missing. Use config.meta_get() for optional meta settings and config.meta_require() when a meta value is mandatory.
What are dbt Jinja filters and when should I use as_bool, as_number, and as_native?
dbt Jinja filters coerce Jinja output into specific Python types. as_bool converts a value to a boolean, as_number converts it to a numeric type, and as_native returns the native Python type such as a list, dict, or tuple. These are especially important when using env_var() since environment variables are always returned as strings. For example, {{ env_var('DB_PORT') | as_number }} ensures the port is treated as an integer, not a string.
What does run_query() return and how do I use the result?
run_query() executes SQL and returns an Agate table object, not a Python list. To use the result, you need to extract values from it. The most common pattern is accessing the first column with .columns[0].values(). Always wrap run_query() inside an {% if execute %} block to avoid errors during the parse phase when no SQL has been run yet.
What does the execute variable do and why does it matter?
execute is set to True only when dbt is actually running SQL against the database (during dbt run or dbt test). During the parse phase, execute is False and no SQL is executed. This matters when your Jinja logic depends on query results. If you try to call run_query() without wrapping it in {% if execute %}, dbt will throw a compilation error during parsing because no data has been returned yet.
What is the config variable and how does config.get() differ from config.require()?
The config variable provides access to the configuration set for a dbt model. config.get('key', default='value') safely fetches a config value and returns a default if it is not set. config.require('key') strictly requires the config key to exist and throws a compilation error if it is missing. Use config.get() for optional settings and config.require() when a config value is mandatory for the model to run correctly.
What is the difference between ref() and source() in dbt?
ref() is used to reference other dbt models within your project. It builds the dependency graph and resolves the correct schema and table name at compile time. source() is used to reference raw data tables defined in your sources.yml file. Use ref() when pointing to a dbt model, and source() when pointing to upstream raw data. This distinction is how dbt tracks lineage end to end.
What is the difference between var() and env_var() in dbt?
var() pulls values defined in dbt_project.yml or passed via the CLI with --vars. It is best for project-level configuration like date ranges or feature flags. env_var() reads environment variables from the operating system or your dbt platform, making it suitable for secrets, credentials, and environment-specific settings. Never use env_var() directly in model SQL for sensitive values since those values may appear in compiled SQL or logs. Use DBT_ENV_SECRET_ prefixed variables for secrets.
What is the modules variable in dbt Jinja and what can it do?
The modules variable gives you access to built-in Python standard library modules directly inside Jinja. The available modules include datetime, pytz, re, and itertools. This makes it possible to work with dates, run regex operations, and manipulate iterables inside your macros without writing a Python model. A common use case is getting the current date: {% set today = modules.datetime.date.today() %}.
What is the target variable and what information can I access from it?
target contains information about your active dbt profile connection. You can access target.name (the name of your target, such as dev or prod), target.schema, target.database, and target.type (the warehouse adapter). It is widely used in macros to write conditional logic that behaves differently across environments, for example only enabling certain tests or materializations in production.
What is the this variable and how is it used?
{{ this }} represents the database object of the current model being compiled. It gives you access to this.database, this.schema, and this.name. It is most commonly used in incremental models to filter new rows against the existing table, for example: WHERE updated_at > (SELECT MAX(updated_at) FROM {{ this }}). It saves you from hardcoding schema or table names.
When should I use log() vs print() in dbt macros?
Both write messages to stdout, but log(msg, info=True) writes to both the log file and stdout, while log(msg, info=False) writes only to the log file. print() is equivalent to log() with info=True. Use log() with info=False for verbose debugging you only want in logs. Use print() or log(..., info=True) when you need the message visible during an active dbt run.






