Snowflake DCM Projects — Extended capabilities (early access)

Introduction

This document describes a rolling set of new DCM Project capabilities that are available in private preview to selected customers. These features extend the core DCM Projects functionality with additional object types and deployment capabilities.

Over time, this document will be extended with new capabilities as they become available for early testing. Once a capability is sufficiently tested and stable, it will progress into the Public Preview release of DCM Projects and be removed from this document.

Early access for the following DCM capabilities is currently available in private preview:

Note

For the main DCM documentation of all publicly available functionality, see Snowflake DCM Projects.

DEFINE SEMANTIC VIEW

You can define Semantic Views directly in DCM Projects. Every deployment of a definition change reconciles the full semantic view definition: tables, relationships, facts, dimensions, metrics, AI instructions, and verified queries.

DEFINE SEMANTIC VIEW DEMO{{env_suffix}}.ANALYTICS.SALES_METRICS
  TABLES (
    orders AS DEMO{{env_suffix}}.SALES.ORDERS
      PRIMARY KEY (ORDER_ID),
    customers AS DEMO{{env_suffix}}.SALES.CUSTOMERS
      PRIMARY KEY (CUSTOMER_ID)
  )
  RELATIONSHIPS (
    orders (CUSTOMER_ID) REFERENCES customers (CUSTOMER_ID)
  )
  DIMENSIONS (
    orders.ORDER_DATE AS orders.ORDER_DATE,
    customers.COUNTRY   AS customers.COUNTRY
  )
  METRICS (
    orders.TOTAL_REVENUE AS SUM(orders.AMOUNT),
    orders.ORDER_COUNT   AS COUNT(orders.ORDER_ID)
  )
  COMMENT = 'Sales metrics semantic view for Cortex Analyst';

Functional limitations

  • All defined constraints and relationships must be named.
  • All CREATE OR ALTER SEMANTIC VIEW usage notes apply, including that tags on the semantic view or its members can’t be added or changed through the statement. Any existing tags are preserved.

DEFINE STREAMLIT

You can define one or more Streamlit apps, their infrastructure, underlying tables, and access control together in a single DCM Project folder, then deploy everything to any environment with one command.

This is especially useful for dashboard and data app deployments that depend on objects (tables, views, dynamic tables) also managed by DCM. The entire stack (data pipeline and the app consuming it) can be version-controlled and promoted through environments together.

Create a DCM Project for Streamlit

You can take your existing Streamlit app folder, which includes:

  • streamlit_app.py (or any entrypoint file)
  • environment.yml (for warehouse runtime) or requirements.txt or pyproject.toml (for container runtime)
  • Any supporting Python modules, pages, or asset files

and move it inside the sources/ folder of your DCM Project, since the Snowflake CLI only uploads files from the sources/ folder hierarchy. Place it outside of sources/definitions/ and organize it in any subfolder structure you like, for example sources/streamlit/my_dashboard/.

my_dcm_project/
├── manifest.yml
└── sources/
    ├── definitions/
    │   ├── pipeline.sql
    │   ├── access.sql
    │   └── dashboard.sql         ← DEFINE STREAMLIT statement
    └── streamlit/
        └── my_dashboard/         ← path referenced in FROM clause
            ├── streamlit_app.py
            ├── page_2.py
            ├── pyproject.toml
            └── snowflake.yml

Then add the DEFINE STREAMLIT statement to your DCM definitions with:

  • The fully qualified name for the Streamlit object
  • The relative path from the manifest to the Streamlit folder (always starting with sources/)
  • The entrypoint file name (MAIN_FILE)
  • The warehouse to use for query execution (QUERY_WAREHOUSE)
  • The compute pool and runtime (COMPUTE_POOL, RUNTIME_NAME) for container-runtime apps
  • An optional display title (TITLE)
  • Any external access integrations (EXTERNAL_ACCESS_INTEGRATIONS) and stage imports (IMPORTS) the app requires
define streamlit DEMO{{env_suffix}}.SERVE.MY_DASHBOARD
    from 'sources/streamlit/my_dashboard'    -- relative path from manifest to Streamlit folder
    main_file = 'streamlit_app.py'
    query_warehouse = DEMO_WH{{env_suffix}}
    compute_pool = SYSTEM_COMPUTE_POOL_CPU
    runtime_name = SYSTEM$ST_CONTAINER_RUNTIME_PY3_11
    title = 'My Dashboard'
    external_access_integrations = ()
    imports = ()
;

Plan & deploy a DCM Project with a Streamlit app

Run your regular DCM plan and deploy commands. If either the DEFINE STREAMLIT statement in your definitions or the file hash for any of the files within the Streamlit app folder has changed since the last successful deployment, PLAN shows the Streamlit object as part of the changeset. DEPLOY replaces any modified files and creates a new version.

PLAN only validates that the Streamlit object can be created. It doesn’t test whether the app itself will run successfully when started.

After the first successful deployment, the Streamlit app is immediately live. DCM automatically initializes the live version after creating the Streamlit object, so you don’t need to run ALTER STREAMLIT manually.

Removing the DEFINE STREAMLIT statement drops the Streamlit object on the next deployment.

Functional limitations

  • DCM Jinja templating variables are not passed through to Streamlit Python files. You can use Jinja in the DEFINE STREAMLIT statement itself (for example, to set the warehouse or compute pool name), but not inside your app code.

    • To reference environment-specific objects from inside your Streamlit app at runtime, query the active context using CURRENT_DATABASE(), CURRENT_SCHEMA(), or similar functions to infer the environment.
  • Only relative paths to the Streamlit folder are supported. You can’t specify a path to another repo or folder outside of the DCM Project.

  • PLAN DELTA doesn’t yet detect changes to the DEFINE STREAMLIT statement or to files within the Streamlit app folder. While this is in early access, run a full PLAN to see these changes reflected in the changeset.

DEFINE DBT PROJECT

You can define a dbt project, its orchestration, infrastructure, and access control together in a single DCM Project folder, then deploy everything to any environment with one command.

Most commonly used is the combination of dbt projects + Tasks to execute dbt test and dbt run on a defined schedule. You can define a DAG of Tasks to orchestrate runs of different dbt projects or individual models.

Create a DCM Project for dbt

You can take your existing dbt project folder, which includes:

  • models
  • dbt_project.yml
  • packages.yml
  • profiles.yml

and move it inside the sources/ folder of your DCM Project, since the Snowflake CLI only uploads files from the sources/ folder hierarchy. Place it outside of sources/definitions/ and organize it in any subfolder structure you like, for example sources/dbt/dbt_pipeline/.

my_dcm_project/
├── manifest.yml
└── sources/
    ├── definitions/
    │   ├── pipeline.sql          ← DEFINE DBT PROJECT statement
    │   ├── access.sql
    │   └── infra.sql
    └── dbt/
        └── dbt_pipeline/         ← path referenced in FROM clause
            ├── dbt_project.yml
            ├── packages.yml
            ├── profiles.yml
            └── models/

Then add the DEFINE DBT PROJECT statement to your DCM definitions with:

  • The relative path from the manifest to the dbt folder (always starting with sources/)
  • A default target (which can use jinja templating to match the DCM deployment target)

In addition, you can add Tasks to execute dbt commands after the deployment as well as grants on the dbt project object or future tables and views.

define dbt project {{db}}.PROJECTS.DBT_PIPELINE
    from 'sources/dbt/dbt_pipeline'    --relative path from manifest to dbt folder
    default_target = '{{dbt_env}}'
;


define task {{db}}.PROJECTS.RUN_DBT_PIPELINE  -- optional: Task(s) to execute your deployed dbt project
    warehouse = {{wh}}
    schedule = '60 MINUTE'
    started     -- (optional) new DCM-specific property that defines the target-state after a DCM deployment
  as
    execute dbt project {{db}}.PROJECTS.DBT_PIPELINE args='run';

define task {{db}}.PROJECTS.TEST_DBT_PIPELINE
    warehouse = {{wh}}
    after {{db}}.PROJECTS.RUN_DBT_PIPELINE
    started
  as
    execute dbt project {{db}}.PROJECTS.DBT_PIPELINE args='test';

If you need to run dbt deps to get external packages, you can run CREATE NETWORK RULE IF NOT EXISTS and CREATE EXTERNAL ACCESS INTEGRATION IF NOT EXISTS in a DCM pre-hook (DCM Hooks are also part of this private preview).

Pass DCM variables to dbt

DCM Jinja templating and dbt templating variables are completely isolated. There’s no automatic pass-through between the DCM manifest.yml configuration and the dbt profiles.yml targets. The two configurations must be maintained separately and kept in sync.

If you need values from the DCM templating context inside a dbt run (for example, the active dbt target), pass them explicitly through the args of the EXECUTE DBT PROJECT statement. Jinja in args is rendered by DCM before the command is executed, so any DCM templating variable can be injected.

define dbt project DCM_DEMO_2_MARKETING{{env_suffix}}.PROJECTS.DBT_PIPELINE
    from 'sources/dbt/dbt_pipeline'
    default_target = '{{dbt_env}}'
;


-- Task graph to schedule dbt project test and run
define task DCM_DEMO_2_MARKETING{{env_suffix}}.PROJECTS.DBT_PIPELINE_RUN
    warehouse = DCM_DEMO_2_MARKETING_WH{{env_suffix}}
    schedule = '60 MINUTE'
    started
  as
    execute dbt project DCM_DEMO_2_MARKETING{{env_suffix}}.PROJECTS.DBT_PIPELINE
        args='run --target {{dbt_env}}'
;

Plan & deploy a DCM Project for dbt

Run your regular DCM plan and deploy commands. If the DEFINE DBT PROJECT statement in your definitions has changed since the last successful deployment, then PLAN will:

  • Render the jinja templating
  • Compile the entire DCM Project
  • Show the dbt project as part of the plan output

The dbt project is compiled during DEPLOY, not during PLAN. PLAN only validates that the dbt project object can be created successfully. It doesn’t check whether the dbt project will run successfully.

Tables created by dbt don’t show as “DCM managed entities” because they aren’t defined directly in the DCM definitions. Removing the DEFINE DBT PROJECT statement drops the dbt project object on the next deployment, but it won’t drop the tables created by dbt.

You can also consider creating a new DCM Project for dbt on top of an existing “platform” project.

Functional limitations

  • PLAN and DEPLOY output only show the operation for a Snowflake dbt project object (CREATE / ALTER / DROP) and don’t show more granular changes in the dbt project configuration or models.
  • Dependencies: dbt models can refer to other objects defined in DCM, but other DCM objects can’t reference tables created by dbt, meaning dbt projects can’t have downstream dependencies.
  • Currently, only relative paths to dbt project files are supported. You can’t specify a path to another repo or folder outside of the DCM Project.
  • PLAN DELTA doesn’t yet detect changes to the DEFINE DBT PROJECT statement or to files within the dbt project folder. While this is in early access, run a full PLAN to see these changes reflected in the changeset.

DEFINE CODE BUNDLE

You can define Code Bundles directly in DCM Projects. Code Bundles package and run non-SQL jobs (such as Python) on Snowflake compute. DCM manages the bundle lifecycle (CREATE, ALTER, DROP) across environments using Jinja templating.

Note

Code Bundles are part of the “Pipeline Builder” private preview, and require an additional preview parameter enabled before DEFINE CODE BUNDLE works in DCM. If PLAN fails because the statement isn’t recognized, this is expected. Reach out to have the parameter enabled for your account.

Place the bundle source files inside the sources/ folder of your DCM Project, then reference that folder with a relative path in the FROM clause. A bundle folder contains the code_bundle.yml specification, the notebook that serves as the entry point, and any Python helper modules the notebook imports:

my_dcm_project/
├── manifest.yml
└── sources/
    ├── definitions/
    │   └── jobs.sql              ← DEFINE CODE BUNDLE statement
    └── code_bundles/
        └── my_job/               ← path referenced in FROM clause
            ├── my_job.ipynb      ← entry point (notebook)
            ├── helpers.py        ← helper module imported by the notebook
            └── code_bundle.yml

Then add the DEFINE CODE BUNDLE statement to your DCM definitions:

DEFINE CODE BUNDLE DEMO{{env_suffix}}.JOBS.MY_JOB
    FROM 'sources/code_bundles/my_job'    -- relative path from manifest to the bundle folder
    COMMENT = 'Python job managed by DCM';

The entry point is specified when you execute the bundle, for example from a Task, by pointing ENTRYPOINT at the notebook:

EXECUTE CODE BUNDLE DEMO{{env_suffix}}.JOBS.MY_JOB
    ENTRYPOINT = 'my_job.ipynb';

For the bundle specification, compute options, dependencies, and execution details, see Snowflake Code Bundles.

Functional limitations

  • Only relative paths to the bundle folder are supported. You can’t specify a path to another repo or folder outside of the DCM Project.
  • PLAN only validates that the Code Bundle object can be created successfully. It doesn’t check whether the bundled code will run successfully.
  • PLAN DELTA doesn’t yet detect changes to the DEFINE CODE BUNDLE statement or to files within the bundle folder. While this is in early access, run a full PLAN to see these changes reflected in the changeset.

DEFINE SECRET

You can define and deploy a Secret in DCM Projects without revealing it in your definitions, repo code, artifacts, or logs. DEFINE SECRET supports all properties of CREATE SECRET for the following secret types: GENERIC_STRING, PASSWORD, OAUTH2, and CLOUD_PROVIDER_TOKEN.

Rotating a masked property shows in the changeset as an ALTER operation, but the value renders as ******** on both sides of the diff, so you can see that the value has changed.

Examples:

DEFINE SECRET DEMO{{env_suffix}}.PROJECTS.THIRD_PARTY_API_KEY
    TYPE = GENERIC_STRING
    SECRET_STRING = {{ _snow.env_secret("API_KEY") }}
    COMMENT = 'API key for the third-party billing service';

An OAUTH2 secret references an existing API_AUTHENTICATION security integration and supplies its refresh token the same way:

DEFINE SECRET DEMO{{env_suffix}}.PROJECTS.OAUTH_CREDENTIAL
    TYPE = OAUTH2
    API_AUTHENTICATION = MY_OAUTH_INTEGRATION
    OAUTH_REFRESH_TOKEN = {{ _snow.env_secret("OAUTH_REFRESH_TOKEN") }};

Functional limitations

  • Every property required for the secret’s type must be specified on every deployment. Omitting a property that a previous deployment set doesn’t preserve its old value, the property is cleared instead.

Warning

Never write a sensitive property (SECRET_STRING, PASSWORD, or OAUTH_REFRESH_TOKEN) as a plain text literal in a definition file. DCM stores the rendered definition, including any literal value it contains, as plain text on the project’s stage. Always supply these values through _snow.env_secret() instead.

Environment variables and secrets

DCM Projects can declare environment variables and secrets in the manifest, then reference them from Jinja templating and directly in SQL properties. This keeps sensitive values, per-environment configuration, and CI/CD-supplied values out of your definition files and Git history.

Note

You can supply values for declared environment variables and secrets only from the Snowflake CLI or from SQL. Workspaces doesn’t support entering these values yet.

Declare env_vars and env_secrets in the manifest

Add optional env_vars and env_secrets sections under templating in manifest.yml. Each entry is a single-key mapping, where the key is the declared name. Do not write any values for the keys in the manifest file.

Example:

targets:
  ...
  
templating:
  env_vars:
    - BUILD_NUMBER:
    - DEPLOYMENT_REGION:
  env_secrets:
    - API_KEY:

  configurations:
    ...

env_vars and env_secrets are declared and referenced the same way. The only difference is that DCM masks secret values wherever it would otherwise surface them, including PLAN/DEPLOY changeset output, deployment history artifacts and logs.

Reference declared names in definition files

Reference a declared name with _snow.env_var("NAME") or _snow.env_secret("NAME") inside a definition file.

Example:

DEFINE TASK DEMO{{env_suffix}}.PROJECTS.NIGHTLY_BUILD
    COMMENT = 'build {{ _snow.env_var("BUILD_NUMBER") }}'
    WAREHOUSE = DEMO_WH{{env_suffix}}
AS SELECT 1;

Use _snow.env_secret("NAME") the same way, most commonly to supply a secret’s value in a DEFINE SECRET statement.

Using a name that was never declared or declaring a name but never supplying a value for it will result in an error during PLAN or DEPLOY.

Supply values from the CLI

Note

Requires Snowflake CLI version 3.24 or later.

The Snowflake CLI collects a value for every declared name from the shell environment when you run snow dcm deploy, plan, or preview and forwards the values with the deployment. Export the variables in your shell, or in your CI/CD job, before running the command:

export BUILD_NUMBER=482
export DEPLOYMENT_REGION=us-east-1
export API_KEY=...

snow dcm deploy

A declared name that isn’t present in the shell doesn’t fail the command by itself. DCM omits it from the deployment, and only reports an error if a definition actually needs it to render.

The CLI submits the collected values to Snowflake as a bind variable, not as literal text in the SQL statement. The values themselves never appear in Query History or in the plain SQL text of the underlying EXECUTE DCM PROJECT statement.

Supply values from a .env file

Pass --env-file/-e with a path to a KEY=VALUE file to source declared values from a file instead of exporting them in your shell. This is useful for CI/CD jobs, and for keeping a team’s non-secret defaults in one place:

snow dcm deploy --env-file .env
# .env
BUILD_NUMBER=482
DEPLOYMENT_REGION=us-east-1

For a name declared in both places, the shell value wins. The file only fills in names the shell doesn’t already provide.

Quote a value that contains # or has leading or trailing whitespace, or the value is silently truncated at the #, or trimmed.

Variable interpolation ($VAR or ${VAR}) isn’t supported. A literal $ in a value is never rewritten.

Whether a value is declared as env_vars or env_secrets only changes how DCM handles it once it reaches Snowflake. It doesn’t change how the CLI reads it from the file, so keep a .env file that contains real values out of Git, the same as you would for any file holding credentials.

Supply values from SQL

Both CLI options above are a convenience layer over the same underlying mechanism: an ENVIRONMENT clause on EXECUTE DCM PROJECT that binds a flat JSON object mapping each declared name to its value. You can supply this clause directly, without using the CLI.

ENVIRONMENT only accepts a bind parameter (a client ?, a session variable, or a Snowflake Scripting variable), never a literal string typed into the SQL text. From a client library, bind the JSON string to a ? placeholder the same way you would bind any other parameter. From a worksheet or snow sql, use a Snowflake Scripting block to supply the bind:

EXECUTE IMMEDIATE $$
DECLARE
  env_json VARCHAR DEFAULT '{"BUILD_NUMBER": "482", "API_KEY": "..."}';
  rs RESULTSET;
BEGIN
  rs := (EXECUTE DCM PROJECT TESTDB.TESTSCHEMA.MY_PROJECT DEPLOY ENVIRONMENT (:env_json) FROM @my_stage);
  RETURN TABLE(rs);
END;
$$;

ENVIRONMENT is supported on PLAN, PREVIEW, and DEPLOY. It isn’t available on TEST ALL, or PURGE, since none of those render definition files.

Sensitive values

Values supplied through env_secrets are safe to use anywhere a definition renders, including inside a pre-hook. Unlike a plain templating variable, a secret value is never rendered into plain text SQL, and DCM masks it everywhere it would otherwise show the secret’s value. Use _snow.env_secret() for the case the warning in Pre-hooks for Integrations describes, even inside the hook itself.

Functional limitations

  • _snow is reserved for this and future built-in context functions. Don’t use it as a variable or macro name.

CLI enhancements

An early-access version of the Snowflake CLI includes improvements to several DCM Projects commands. Re-run the same command with --force occasionally to pick up the latest updates to the early-access build:

uv tool install 'git+https://github.com/snowflakedb/snowflake-cli.git@dcm-early-access'
uv tool install --force 'git+https://github.com/snowflakedb/snowflake-cli.git@dcm-early-access'

To revert to the latest official release on main:

uv tool uninstall snowflake-cli
uv tool install snowflake-cli

Note

Details of these improvements (such as syntax and output format) are subject to change while they’re in early access.

All of the commands (except snow dcm init) support the --save-output flag, which saves the command output as a .json file under out/.

snow dcm compile (new command)

snow dcm compile runs a static analysis of all DCM definitions and returns any errors or warnings found, grouped by file and entity. It’s intended for quickly checking iterative definition changes and catching errors before committing.

  • Validates syntax and dependencies
  • Runs faster than PLAN, but doesn’t catch all possible errors. (Always run PLAN to preview changes before deploying)
  • Shows a compressed file upload summary (file counter per path) with a progress bar

snow dcm dependencies (new command)

snow dcm dependencies runs a static analysis of all DCM definitions and builds a Mermaid flowchart representing the dependencies between all objects in the project (tables, dynamic tables, views, functions, procedures, and tasks).

The diagram is written to out/dependencies.md. The CLI prints a link to the file so you can open it in your IDE’s Markdown preview and explore the dependency graph visually.

Note that these dependencies refer to the deployment of objects (CREATE). It does not resolve run-time dependencies (for example, a Task that calls a stored procedure).

  • Generate a dependency diagram for the current project:
    snow dcm dependencies
    
    snow dcm dependencies --target dev
    

snow dcm init (new command)

snow dcm init is the starting point for two common workflows: creating a brand-new empty DCM Project, or deploying an existing set of DCM definitions (from a repository or local path) to a new target environment. In both cases it bootstraps the project in a single run: it writes or updates a manifest.yml, creates the DCM Project object in Snowflake, and provisions any missing supporting objects (database, schema, warehouse). Before making any change, it prints a summary of every action and asks for confirmation. Nothing is created if you decline.

To start a new project the init process will walk you through all required steps for setting up a new project structure:

snow dcm init -c my_connection

If you want to use an existing project folder and add a new target for a new account, then run init from a directory that already contains a manifest.yml. A new target block is appended and your existing definitions are left untouched:

snow dcm init --target prod_2 -c my_connection

During a run, init resolves everything a target needs:

  • Target name — defaults to your account alias; re-prompts if the name is invalid or already used.
  • DCM Project object name — defaults to the target name. Identifiers with special characters are automatically wrapped in double quotes.
  • Database and schema — uses your connection’s defaults (or prompts when there are none) and creates them if they don’t exist.
  • Project owner — uses your current role, or prompts if it can’t be determined.
  • Warehouse — uses your connection’s warehouse, or provisions an X-Small DCM_WH (or a name you choose) and tells you how to configure it.

For automation and CI, pass --force to approve all changes non-interactively. --force requires --target; if that target already exists it’s reused as-is rather than failing:

snow dcm init \
  --project-name my_project \
  --target dev \
  --project-identifier MY_DB.MY_SCHEMA.MY_PROJECT \
  --force \
  -c my_connection

The following options control init behavior:

OptionDescription
--project-name <name>Create a new project in a subfolder of this name. Omit to add a target to an existing manifest.yml.
--target <name>Name of the target to create in the manifest. Defaults to the account alias. Required with --force.
--project-identifier <id>Identifier of the DCM Project object (for example, MY_DB.MY_SCHEMA.MY_PROJECT). Defaults to the target name.
--if-not-existsDo nothing if the DCM Project object already exists in Snowflake.
--forceApprove all changes non-interactively.

Pre-hooks for Integrations

DDL Pre-hooks are intended as an interim solution for defining integrations until they are supported natively in DCM using DEFINE statements. DDL Hooks do not offer full functional parity to regular DCM definitions.

Capabilities of DDL Pre-hooks

  • Each DCM Project can contain only 1 pre-hook
  • The pre-hook can contain multiple DDL statements
  • DDL statements inside the hook are executed in the order they are defined
  • The hook supports only 2 types of commands:
  • CREATE IF NOT EXISTS (recommended)
    • For one-time execution to create the object
    • Skipped any time an integration with this name already exists
  • CREATE OR REPLACE
    • Executed at every DCM deployment
    • Use when the definition of an existing object has changed and should be replaced completely
  • Only DDL statements are supported (no USE, no SET, no COPY INTO…)

Key advantages of pre-hooks compared to custom SQL pre-scripts

  1. Pre-hooks are plannable. Other DCM definitions can declare dependencies on objects created in the pre-hook.
    • Example: A Notification Integration defined in the pre-hook can be referenced by an Alert defined in DCM definitions.
  2. Pre-hooks support Jinja templating, using the same variables as the rest of the DCM Project, including _snow.env_var() and _snow.env_secret().

Functional limitations

  • Create statements from pre-hooks show as operations in the PLAN changeset and the deployment history, but don’t include granular details about their individual properties.
  • Errors from executing pre-hooks don’t show the exact error line and in some cases not the full stack-trace.
  • Removing a DDL statement from a pre-hook does NOT drop the object.
  • Pre-hooks can’t be defined inside Jinja loops, as it would create multiple pre-hooks. However, Jinja code including loops can be used inside a hook.

Warning

Don’t use a plain templating variable for sensitive information or credentials in a pre-hook. The rendered SQL definitions don’t redact any values inserted that way. Use _snow.env_secret() inside the hook instead: see Environment variables and secrets.

Comparison between DCM definitions, DCM pre-hooks, custom SQL pre-scripts

FunctionalityDCM DefinitionsDCM pre-hooksCustom SQL scripts
Uses DCM Jinja templating values🚫
Plannable dependencies🚫
DDL operations visible in PLAN output🚫
DDL operations stored in DCM deployment artifacts🚫
Removing definition -> drops object🚫🚫
Changed definition -> alters object✅ (when using CREATE OR REPLACE)🚫
Automatically executed in the correct order based on dependencies🚫🚫

Supported object types for DDL Hooks

Only integration object types are supported:

  • API Integration
  • Notification Integration
  • External Access Integration
  • Catalog Integration
  • Security Integration
  • Storage Integration

Once these object types are supported natively with DCM DEFINE statements, the hook support will be deprecated.

Examples:

ATTACH PRE_HOOK
AS [

    CREATE API INTEGRATION IF NOT EXISTS GITHUB_API_{{env_suffix}}
        API_PROVIDER = git_https_api
        API_ALLOWED_PREFIXES = ('https://github.com')
        ALLOWED_AUTHENTICATION_SECRETS = all
        ENABLED = true;

    CREATE NOTIFICATION INTEGRATION IF NOT EXISTS DCM_EMAIL_NOTIFICATIONS_{{env_suffix}}
        TYPE = EMAIL
        ENABLED = true
        ALLOWED_RECIPIENTS = ('example@example.com');

];