Contribute a dbt Core v2 adapter
This guide is for dbt Core v2. For dbt Core v1, see Build, test, document, and promote adapters.
Step 1: Introduction
dbt Core v2 adapters work very differently from v1, and it's worth understanding why before diving in.
In dbt Core v1, every adapter was a standalone Python package, independently maintained by the community. That model didn't scale: maintenance cost grew with every new warehouse added, bugs had to be fixed separately in each package, and shared improvements rarely made it back across the ecosystem.
dbt Core v2 flips this entirely. Adapters now live inside a single Rust monorepo, organized by feature area rather than by warehouse. A fix in the auth module benefits every adapter at once. When you contribute a new adapter, you're extending shared code, not building a whole new package from scratch. In Rust terms: adding arms to existing match expressions. The more adapters that exist, the easier each new adapter becomes. Your contribution makes the whole ecosystem better.
Another advantage of dbt Core v2: connection management lives in its own lane outside of the adapter. In v1, each adapter had to own its connection logic, wrapping vendor SDKs or implementing the Python DB API spec. In v2, ADBC drivers handle that responsibility: pre-compiled binaries that you register but don't write. For a full explanation of ADBC and how dbt Core v2 uses it, see ADBC in dbt Core v2.
What you need to contribute is the exact logic that varies by warehouse: credentials, relation naming, macros, and catalog queries. A complete community adapter touches ~13 files; that's the bar we're aiming for.
This guide walks you through the architecture, crate structure, and how to contribute a dbt Core v2 adapter step by step. I’m Hope Watson, product manager for dbt Core v2 adapters at dbt Labs, and I put this together to help design, document, and shepherd this process for the community in the v2 world.
The Exasol adapter, contributed by Marco Nätlitz, is used as the reference example throughout. The full file breakdown in the reference section defines exactly what you're building.
How v1 vs. v2 adapters differ
| Loading table... |
What you're building
As a community contributor, you're building the foundation: connect your warehouse, run dbt macros, and support basic materializations. Once your adapter is in place, dbt build and dbt run should work. The ~13 files in the reference section define the complete scope.
Think of your adapter contribution as the bridge between dbt Core v2 and your warehouse: everything dbt needs to talk to it, nothing more. The architecture diagram below shows where your work fits in the stack.
Step 2: Prerequisites
Rust familiarity: You don't need to be a Rust expert. You need to read Rust, understand enum match expressions, and make sense of compiler errors. If Rust is new to you, skim The Rust Book Chapter 6 (enums and pattern matching). Those are the concepts you'll encounter most.
dbt fundamentals: Understand how profiles.yml works, what materializations are, and what adapter dispatch macros do.
Deep knowledge of your warehouse: As you work through this guide, you'll need to know how your warehouse behaves:
- What character does it use for quoting identifiers?
- Does it support two-part or three-part relation names?
- What connection parameters does it require?
- How does it handle transactions?
- What datatypes map to standard SQL types like string, timestamp, boolean?
- What's the most efficient way to list columns in a schema?
A note on AI-assisted development: dbt Core v2's architecture is naturally legible to AI coding tools. Match arms are explicit, compiler errors are precise, and the scope of each file is narrow. You don't need to use an LLM, but if you do, the structure works in your favor.
Your ADBC driver
Do you have an ADBC driver for your warehouse? If no, stop here. The ADBC driver is a firm requirement before creating a dbt Core v2 adapter.
Check these sources to find out if one exists for your warehouse:
- apache/arrow-adbc: upstream community repo
- dbt-labs/arrow-adbc: the dbt Labs fork
- ADBC driver foundry: primary community home for ADBC drivers, with active drivers and Rust/Go frameworks for building new ones
- Your warehouse vendor's own GitHub org
If no driver exists yet, building one is a separate project that comes before the adapter contribution. This is outside the scope of dbt Labs. Columnar specializes in building ADBC drivers and may be a useful resource.
dbt Labs is working toward a model where community drivers can be distributed and loaded safely via signed binaries, similar to how operating systems verify installers. The goal is to make third-party driver installation as seamless and trustworthy as first-party. This isn't in place yet, but dbt Labs is considering this direction.
Step 3: Understanding the codebase shape before you build
The vertical model
dbt Core v2 organizes adapter logic by capability, not by warehouse. There's no SnowflakeAdapter class, no BigQueryAdapter class. Instead, a single shared codebase handles all warehouses, with warehouse-specific behavior driven by match adapter_type() expressions. When you add a new warehouse, you're adding arms to those expressions across a set of feature areas, auth, relations, catalog introspection, Jinja macros, rather than creating a new top-level package.
The structural diagram below shows how the layers fit together. Your work lives in the ADAPTER layer: the crates that handle warehouse identity, credential resolution, relation logic, and Jinja dispatch. XDBC (driver loading and connection pooling) sits just below and has a small registration step too.
Crate map
In Rust, a crate is a package: the unit of compilation, roughly equivalent to a "library" or "module" in other languages. The dbt-core repo is a monorepo of multiple crates, each responsible for one vertical slice of functionality across all warehouses. This is a quick-reference map of the six crates you'll touch to build your adapter, in the order you'll work through them in Step 5.
| Loading table... |
Where your adapter fits in the execution model
By the time your adapter is invoked, all the dbt work is already done. dbt has resolved ref() and source() calls, rendered every Jinja template, and produced dialect-specific SQL. Your adapter receives a finished string and executes it.
dbt resolves ref(), renders Jinja, and hands your adapter a finished string. You execute it; you don't template it.
While you're coding, the compiler enforces completeness. When you add AdapterType::MyWarehouse to the enum, every match adapter_type() block that doesn't handle it fails at that exact line. Your to-do list is always visible. For example:
// You add your variant to the enum in dbt-adapter-core:
pub enum AdapterType {
Snowflake,
BigQuery,
DuckDb,
Trino,
MyWarehouse, // ← you added this
}
// Now every match block in the codebase must handle it.
// This one in adapter_impl.rs doesn't yet:
match self.adapter_type() {
AdapterType::Snowflake => { ... }
AdapterType::BigQuery => { ... }
AdapterType::DuckDb => { ... }
AdapterType::Trino => { ... }
// missing MyWarehouse → compile error
}
error[E0004]: non-exhaustive patterns: `AdapterType::MyWarehouse` not covered
--> crates/dbt-adapter/src/adapter/adapter_impl.rs:142:18
|
| match self.adapter_type() {
| ^^^^^^^^^^^^^^^^^^^ pattern `AdapterType::MyWarehouse` not covered
Each failure is a concrete implementation task.
Are you porting an existing v1 adapter?
No v1 adapter? Skip to Step 4. If you're porting, use this map to see exactly what transfers, what needs rethinking, and what dbt Labs now owns for you in v2.
Most community contributors aren't building from scratch, they're porting an adapter they already maintain or use in Python for dbt Core v1. If that's you, you have a significant head start, and this is the most realistic path for the vast majority of contributors.
Before writing any Rust, check a couple of things:
- Does a v1 adapter already exist for your warehouse?
Check the trusted adapters and community adapters lists. If one exists, find its GitHub repo: the macro SQL and connection logic are almost directly reusable.
- Did dbt Labs already add a placeholder for your warehouse?
Some warehouses already appear in v2's AdapterType enum but aren't fully implemented yet: the enum variant exists, which means the boilerplate is partially in place. When you add the remaining code, the compiler shows you exactly what's still missing. The warehouses in this state are:
| Loading table... |
For warehouses not yet in AdapterType at all (MySQL, Hive, Vertica, SQL Server, Teradata, etc.), you start from Step 5.1 by adding the AdapterType variant.
What transfers from v1 to v2
| Loading table... |
What doesn't transfer by design
Four categories of v1 code simply don't exist in v2, which means less code to port:
- Connection management: In v1 you owned the full connection lifecycle against the Python DB API. In v2 the ADBC driver handles this entirely; skip anything related to cursors, retries, or connection pooling.
- Query execution: Shared Rust infrastructure handles raw query plumbing (
execute,add_query). You don't implement it. - Adapter class hierarchy: The Python subclass structure is replaced by shared Rust match expressions. You register your adapter; you don't implement execution logic.
- Packaging and distribution: No
setup.py, no PyPI release. dbt Labs ships your adapter once the PR is merged.
Step 4: Development machine setup
# Rust
rustup # install from https://rustup.rs
rustup show # verify
# Go (needed for driver builds)
go version # verify
# Clone the repo
git clone https://github.com/dbt-labs/dbt-core
cd dbt-core
# Verify you can build
cargo build --bin dbt
If you hit Z3 errors:
brew install pkg-config z3
If disk fills during build:
cargo clean # frees old build artifacts; you'll do this often
Development workflow
The core development loop is the same whether you write code manually or with an AI assistant:
- Add
AdapterType::MyWarehouseto the enum (Step 5.1) - Run
cargo build -p <crate>: the compiler lists every match arm missing for your new variant - Use the compiler output + the file you're editing + the equivalent reference file (from the breakdown at the bottom) to write each arm. If using an AI assistant, paste all three in as context.
- Example: to fill in the
quote_chararm, paste the error listingAdapterType::MyWarehouseas missing, thequote_charmatch block fromdbt-adapter-core/src/lib.rs, and the Exasol line (Exasol => '"') as the pattern to follow.
- Example: to fill in the
- Fill in the arm; verify with
cargo buildagain - Repeat for each crate until error-free
Every missing case is a compile error, so an AI assistant always has a precise specification to work from.
What context helps for each arm:
- The file you're editing: paste the relevant
matchblock or function. For example, thematch self.adapter_type()block fromadapter_impl.rsthat needs a new arm. - The equivalent reference file from the breakdown below. For example, when writing your auth module, paste
crates/dbt-auth/src/exasol/mod.rsas the pattern. - The compiler error output. For example:
error[E0004]: non-exhaustive patterns: AdapterType::MyWarehouse not covered - Your warehouse's specifics: system catalog table names and the connection fields from your
profiles.yml.
Watch out for:
- Hallucinated file paths: AI often invents dbt Core v2 paths. Use the file breakdown below as ground truth.
- Always verify with the type checker: run
cargo build -p <crate>after any AI-generated changes. - SQL macro patterns from v1 may not apply cleanly in dbt Core v2. Compare against the reference
adapters.sqlatcrates/dbt-loader/src/dbt_macro_assets/dbt-exasol/macros/adapters.sqlin dbt-labs/dbt-core.
Step 5: Build a new adapter
This step walks you through each crate you need to touch. Work through them in order. Each builds on the last. After each sub-step, run the type checker to catch missed match arms and type errors:
cargo build -p <crate-name>
Replace <crate-name> with the crate you just edited, for example dbt-adapter-core, dbt-xdbc, dbt-schemas, dbt-auth, dbt-adapter, or dbt-loader.
5.1: Register the adapter type
Crate: crates/dbt-adapter-core/
AdapterType is the central enum that identifies your warehouse throughout the entire codebase. Add your variant here first.
Rust's match expressions must handle every possible variant explicitly. So when you add AdapterType::MyWarehouse, every match adapter_type() block that doesn't handle your variant becomes a compile error. Run cargo build -p <crate> and the compiler hands you a complete list of exactly what still needs to be written. Nothing is hidden or implicit.
// crates/dbt-adapter-core/src/lib.rs
pub enum AdapterType {
Postgres, Snowflake, Bigquery, Databricks, Redshift,
Salesforce, Spark, DuckDB, Fabric,
ClickHouse, Athena, Starburst, Trino, Datafusion, Dremio, Oracle,
Exasol, // ← already added
MyWarehouse, // ← add yours here
}
Also add a quote_char arm in the same file. Use double quotes '"' for most warehouses; BigQuery and Databricks use a backtick instead:
// crates/dbt-adapter-core/src/lib.rs
fn quote_char(&self) -> char {
match self {
// ... existing adapters ...
Exasol => '"', // double-quote (most warehouses)
MyWarehouse => '"', // ← add yours here
BigQuery | Databricks => '`',
}
}
5.2: Register the ADBC driver
Crate: crates/dbt-xdbc/
Your driver already exists (covered in Step 2). This step is where you register it so dbt Core v2 knows its library name and how to load it at runtime.
| Loading table... |
The Backend enum maps to the ADBC shared library name (lib<name>.so / <name>.dll / lib<name>.dylib). You're registering its identity so dbt Core v2 knows what to load. You're not writing the driver here.
CDN-distributed vs. manual install
For these 11 adapters, dbt Core v2 automatically downloads the driver on first use. All other adapters require manual installation. Users take one extra setup step. Make this clear in your documentation (Step 7).
| Loading table... |
For custom Arrow type mappings (for example, DuckDB needed this for HUGEINT, UTINYINT): only add warehouse-specific type handling if your driver returns types that Arrow's standard schema doesn't cover. Most warehouses don't need this.
5.3: Add your connection profile
Crate: crates/dbt-schemas/
| Loading table... |
The config struct should include everything a user would put in their profiles.yml for your warehouse. Example from Exasol:
#[derive(Debug, Clone, Serialize, Deserialize, Default, DbtSchema, Merge)]
pub struct ExasolDbConfig {
pub user: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", alias = "pass")]
pub password: Option<String>,
pub host: Option<String>,
pub port: Option<StringOrInteger>,
pub database: Option<String>,
pub schema: Option<String>,
pub encryption: Option<bool>,
pub certificate_validation: Option<bool>,
pub certificate_fingerprint: Option<String>,
pub connection_timeout: Option<StringOrInteger>,
pub threads: Option<StringOrInteger>,
}
After adding the config struct, also add DbConfig::MyWarehouse(Box<MyWarehouseDbConfig>) as a new variant to the DbConfig enum. The compiler will then point you at every place that reads from DbConfig and needs a new case for your warehouse. Follow those errors to wire it in.
5.3.1: Add dbt init profile generation (optional but strongly encouraged)
This is what makes your adapter easy to use. When someone runs dbt init and selects your warehouse, they get a guided prompt that builds their profiles.yml, without documentation hunting or manual YAML editing.
Add support in crates/dbt-init/:
- Register your adapter in
get_available_adapters()incrates/dbt-init/src/profile_setup.rs:
pub fn get_available_adapters() -> &'static [AdapterType] {
&[
// ... existing adapters ...
AdapterType::MyWarehouse, // ← add this
]
}
-
Create a config file
crates/dbt-init/src/adapter_config/<warehouse>_config.rsimplementingInteractiveSetupfor yourDbConfigstruct: define the fieldsdbt initshould prompt for and aset_field()handler. Seepostgres_config.rsas a minimal reference. -
Export it from
crates/dbt-init/src/adapter_config/mod.rs:
pub mod mywarehouse_config;
pub use mywarehouse_config::setup_mywarehouse_profile;
- Add a match arm in
create_profile_for_adapter()inprofile_setup.rs:
AdapterType::MyWarehouse => {
let config = match existing_config {
Some(DbConfig::MyWarehouse(c)) => Some(c),
_ => None,
};
DbConfig::MyWarehouse(setup_mywarehouse_profile(config.map(Box::as_ref))?)
}
5.4: Add authentication
Crate: crates/dbt-auth/
| Loading table... |
The auth module turns a DbConfig into a live, authenticated ADBC connection. At minimum you need basic credential handling. More sophisticated auth (OAuth, SSO, key-pair) can be added incrementally.
The pattern is: read config fields → construct URI → call builder.with_parse_uri(uri), builder.with_username(user), builder.with_password(password).
5.5: Build the adapter layer
Crate: crates/dbt-adapter/
This is the largest step. You're adding warehouse-specific behavior to the shared adapter layer via match adapter_type() arms.
Most adapters, including Exasol, Athena, Trino, Starburst, Dremio, Oracle, and ClickHouse, add match arms directly to the shared files in src/relation/.
Only adapters with highly custom relation logic (Snowflake's multi-part names and case rules; BigQuery's project/dataset structure) have their own subdirectory under src/relation/.
If your warehouse uses standard schema.table or database.schema.table naming with straightforward quoting, you're a simple adapter. Start simple and only add complexity if the compiler forces it.
Relation type and quoting
File: crates/dbt-adapter/src/relation/relation_impl.rs
Add a match arm that sets your quoting policy. The policy controls three things: whether the database is included in fully-qualified names, whether the schema is quoted, and whether the identifier is quoted.
For example, Exasol uses a 2-part name (schema.table, no database prefix) and quotes both:
// crates/dbt-adapter/src/relation/relation_impl.rs
fn include_policy(adapter_type: AdapterType, path: &RelationPath) -> Policy {
match adapter_type {
// ... existing adapters ...
AdapterType::MyWarehouse => Policy::new(false, true, true),
// ↑ ↑ ↑
// database schema identifier
// disabled quoted quoted
_ => Policy::trues(), // default: all parts included and quoted
}
}
Decide up front whether your warehouse uses 2-part or 3-part names, and whether identifiers are case-sensitive. For example, Exasol uppercases unquoted identifiers by default, so all catalog lookup SQL uses upper() comparisons.
File: src/relation/factory.rs
Add your AdapterType to the create_static_relation match, wiring it to RelationStatic (the generic static relation used for Jinja's api.Relation):
Databricks | Spark | Fabric | DuckDB | Exasol | Postgres | Redshift | Salesforce | Bigquery => {
let relation_type = RelationStatic { adapter_type, quoting };
StaticBaseRelationObject::new(Arc::new(relation_type))
}
Catalog introspection
File: src/metadata/get_relation.rs
Add a match arm and a function that queries your warehouse's system catalog to look up a single relation by name. Follow the reference implementations closely. This area of the codebase is expected to evolve:
AdapterType::Exasol => exasol_get_relation(
adapter, state, ctx, conn, database, schema, identifier, token,
),
fn exasol_get_relation(
adapter: &AdapterImpl,
state: &State,
ctx: &QueryCtx,
conn: &mut dyn Connection,
database: &str,
schema: &str,
identifier: &str,
token: CancellationToken,
) -> AdapterResult<Option<Box<dyn BaseRelation>>> {
let q_schema = schema.to_uppercase();
let q_ident = identifier.to_uppercase();
let sql = format!(
"select 'table' as \"type\" from sys.exa_all_tables \
where table_schema = '{q_schema}' and table_name = '{q_ident}' \
union all \
select 'view' from sys.exa_all_views \
where view_schema = '{q_schema}' and view_name = '{q_ident}'"
);
// execute, read result, return relation
}
Use information_schema if your warehouse supports standard SQL, or system catalog tables (sys.*, information_schema.*) as appropriate.
Adapter match arms
File: src/adapter/adapter_impl.rs
After adding AdapterType::MyWarehouse, the compiler will enumerate every match self.adapter_type() block that needs a new arm. Most arms simply delegate to an existing pattern. For example:
// Column builder: delegate to postgres-like builder
Exasol => Ok(Self::build_postgres_like(field, type_ops)),
// Schema column name for listing relations
Exasol => "name",
// DATA_TYPE column name in information schema
AdapterType::Exasol => "DATA_TYPE", // in src/sql_types.rs
For capabilities your adapter doesn't support yet (like valid_incremental_strategies), return unimplemented!(). That's fine for an initial community adapter contribution.
Column builder
File: src/column/column_builder.rs
Add a match arm for how your warehouse's Arrow record batches map to dbt column objects. Most adapters can delegate to build_postgres_like:
Exasol => Ok(Self::build_postgres_like(field, type_ops)),
Only implement custom logic if your warehouse has unusual type handling.
5.6: Write your SQL macros
Crate: crates/dbt-loader/
Create a new directory at src/dbt_macro_assets/dbt-<adapter_type>/.
The loader discovers adapter packages by scanning src/dbt_macro_assets/. You don't need to add any Rust code to register your directory. Creating it and the dbt_project.yml is sufficient.
| Loading table... |
v2 uses the same adapter.dispatch() pattern as v1. Your macros use the <warehouse>__ prefix to override defaults:
{% macro exasol__create_table_as(temporary, relation, sql) -%}
create or replace table {{ relation }} as (
{{ sql }}
)
{%- endmacro %}
{% macro exasol__create_view_as(relation, sql) -%}
create or replace view {{ relation }} as (
{{ sql }}
)
{%- endmacro %}
{% macro exasol__drop_relation(relation) -%}
{% call statement('drop_relation', auto_begin=False) -%}
drop {{ relation.type }} if exists {{ relation }} cascade
{%- endcall %}
{% endmacro %}
{% macro exasol__rename_relation(from_relation, to_relation) -%}
{% call statement('rename_relation') -%}
rename {{ from_relation.type }} {{ from_relation }} to {{ to_relation.identifier }}
{%- endcall %}
{% endmacro %}
Note: rename_relation uses only to_relation.identifier, not the full relation. Exasol's RENAME syntax doesn't take a fully qualified target.
For catalog introspection, use your warehouse's system catalog. For example, Exasol queries sys.* instead of information_schema:
{% macro exasol__list_relations_without_caching(schema_relation) -%}
{% call statement('list_relations_without_caching', fetch_result=True) -%}
select
'{{ schema_relation.database }}' as "database",
table_name as "name",
table_schema as "schema",
'table' as "type"
from sys.exa_all_tables
where upper(table_schema) = upper('{{ schema_relation.schema }}')
union all
select
'{{ schema_relation.database }}' as "database",
view_name as "name",
view_schema as "schema",
'view' as "type"
from sys.exa_all_views
where upper(view_schema) = upper('{{ schema_relation.schema }}')
{%- endcall %}
{{ return(load_result('list_relations_without_caching').table) }}
{%- endmacro %}
{% macro exasol__information_schema_name(database) -%}
sys
{%- endmacro %}
If your warehouse is similar to an existing one (e.g. Postgres-compatible), start by delegating to that dialect's macros and only override where behavior differs:
{% macro mywarehouse__create_table_as(temporary, relation, sql) -%}
{{ return(postgres__create_table_as(temporary, relation, sql)) }}
{%- endmacro %}
Step 6: Test your adapter
Type check after each crate
Run the type checker after completing work in each crate to catch missed match arms and type errors immediately:
cargo build -p dbt-adapter-core
cargo build -p dbt-xdbc
cargo build -p dbt-schemas
cargo build -p dbt-auth
cargo build -p dbt-adapter
cargo build -p dbt-loader
Smoke testing with a dbt project
Run a real dbt build against your warehouse and ensure it builds error-free. At minimum, exercise table, view, incremental, and seed materializations. A clean dbt build on jaffle-shop is one example of an acceptance bar for a community adapter.
# Build the CLI
cargo build --bin dbt
# Create a test project (or clone jaffle-shop)
./target/debug/dbt init
# Run against your warehouse
./target/debug/dbt build --project-dir <your-project>
CI testing
CI testing for community adapter PRs is coordinated with the dbt Labs adapters team: the test infrastructure is not publicly distributed. When your PR is ready, reach out in #adapter-ecosystem on the dbt Community Slack, tag Hope Watson (@Hope Watson (dbt Labs)), and the adapters team will work with you on warehouse validation. Note that this may take some time and coordination.
Community contributors cannot run CI independently. dbt Labs' CI pipeline requires certain checks. For certain adapters, that means warehouse credentials. dbt Labs is still defining this handoff process for dbt Core v2. Expect to coordinate closely with the adapters team, for the approval process to take some time, and for some back-and-forth. If you hit friction, flag it in #adapter-ecosystem.
Step 7: Document your adapter
Once your adapter is merged and available in a release, document it so users can find and configure it.
Write a setup guide
Document the profiles.yml configuration for your warehouse: what fields are required, what's optional, and example values. Follow the format of existing adapter setup guides.
Unlike adapters distributed via the CDN, your users won't get the driver automatically: dbt Core v2 won't download it for them. Your setup guide must explain where to get the driver binary and how to install it so dbt Core v2 can find it at runtime. Without this, users will configure a valid profile and still get a connection error. Include the exact library name dbt Core v2 looks for (e.g. libadbc_driver_<yourwarehouse>.dylib) and where to put it.
General documentation guidelines
- Assume the reader knows dbt fundamentals but is not an expert on your warehouse's inner workings.
- Include a complete working
profiles.ymlexample. - Document any warehouse-specific quirks (e.g. 2-part vs 3-part naming, identifier case sensitivity).
- Link to the warehouse vendor's ADBC driver documentation.
Step 8: Promote your adapter
dbt Labs reviews and merges community adapter PRs into dbt-core. Wait until the PR is merged and the adapter ships in a published release before directing users to it.
Community channels
Join the dbt Community Slack and find:
#adapter-ecosystem: the main channel for adapter developers#db-<yourwarehouse>: if a channel exists for your warehouse, let users know v2 support is available. Note: v1 adapter users will still be on the Python-based adapter and will need to migrate.
Before you announce
Align with the adapters team on: which materializations you're targeting in the initial implementation, any known gaps in your ADBC driver, and timeline. This prevents surprises during review and sets accurate expectations for users.
Reference: File-by-file implementation guide
A community-contributed dbt Core v2 adapter touches roughly 13 files, all in the public dbt-labs/dbt-core repo. The "Exasol example" column shows what it looks like in practice. Substitute your warehouse name and system catalog throughout.
| Loading table... |
Reference: Useful commands
# Type check a specific crate
cargo build -p <crate-name>
# Build the CLI binary
cargo build --bin dbt
# Run a full dbt build against your warehouse
./target/debug/dbt build --project-dir <your-project>
# Free disk space
cargo clean
Was this page helpful?
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.