dbt for Apache Doris
dbt-for-apache-doris enables Python dbt Core projects to transform data in
Apache Doris through the Doris MySQL protocol. It is maintained by the VeloDB
community.
[!IMPORTANT] This adapter is Beta. CI covers lint, Unit tests, and package validation, but not a live Doris cluster. Current-release compatibility and VeloDB verification are pending.
Installation · Quickstart · Compatibility · dbt docs · Doris docs · Issues · Releases
Supported capabilities
Status: ✅ Supported · ❌ Not supported
Feature status and database-version compatibility are separate contracts.
Supported means the documented scope is implemented and tested; explicit
platform boundaries are described alongside each capability.
Materializations
| Capability | Status | Current support and boundaries |
|---|---|---|
| Table | ✅ Supported | Duplicate Key CTAS; configurable HASH distribution, integer buckets, RANGE/LIST partitions, properties, contracts, docs, grants, and hooks. Unique Key creation belongs to incremental merge |
| View | ✅ Supported | Standard lifecycle, contracts, docs, grants, and hooks; relation-type switching is not zero-downtime |
| Incremental | ✅ Supported | Four strategies and every on_schema_change mode; boundaries are listed below |
| Snapshot | ✅ Supported | check/timestamp, hard-delete modes, schema evolution, atomic replacement, and recovery; same-target runs must be serialized by the scheduler |
| Materialized view | ✅ Supported | Standard dbt materialized_view, implemented with Doris Async MV; build/refresh lifecycle, task waiting, configuration changes, atomic replacement, and recovery. Same-target dbt runs must be serialized by the scheduler |
| Seed | ✅ Supported | CSV loading, type inference, column_types, and ref |
| Ephemeral | ✅ Supported | Compiled and inlined by dbt Core |
dbt capabilities
| Capability | Status | Current support and boundaries |
|---|---|---|
| Sources and freshness | ✅ Supported | loaded_at_field, filter, and loaded_at_query; cross-database uses database-as-schema, not External Catalog |
| Data tests | ✅ Supported | Singular, generic, ephemeral, and store_failures paths |
| dbt Unit tests | ✅ Supported | Inline-row and CSV fixtures, case-insensitive columns, invalid-input validation, quoted reserved words, Doris-adapted data-type fixtures, and non-truncating VARCHAR fixtures |
| Model contracts | ✅ Supported | Column names/types for Table, View, and Incremental; not database PK/NOT NULL constraints |
| Persisted docs | ✅ Supported | Relation and column comments for Table, View, Incremental, Snapshot, Seed, and Async MV; updating View comments or comment text containing both quote delimiters may require recreation/full refresh |
| Grants | ✅ Supported | Reconciles supported Doris table privileges for user and user@host principals on Table, View, Incremental, Seed, Snapshot, and Async MV; role principals are not reconciled |
| Hooks | ✅ Supported | Pre-hooks and post-hooks across adapter materializations; Doris does not provide transactional rollback for hook side effects |
| Internal metadata and dbt docs catalog | ✅ Supported | Relation discovery and docs catalog for Doris databases, tables, views, columns, comments, and Async MVs |
| Cross-database sources | ✅ Supported | Sources in other Doris databases, including database-only source definitions; External Catalog three-part names are not supported |
| Advanced metadata / External Catalog | ❌ Not supported | Catalogs V2, metadata-by-relation, single-relation catalog, last-modified metadata, and External Catalog three-part namespaces are not declared |
Compatibility
| Component | Declared or runtime constraint | Current evidence or status |
|---|---|---|
| Python | >=3.10 |
Unit CI covers 3.10 and 3.14; the distribution-build job uses 3.12 |
| dbt Core | >=1.12,<1.13 |
Declared lower bound is 1.12.0; Python dbt Core v1 only. Fusion/v2 compatibility is not claimed |
| MySQL connector | >=8.0.33 |
Installed automatically with the adapter |
| Apache Doris | No package-wide minimum has been declared | Historical exact-release evidence exists, but the current release-candidate SHA still needs a complete live matrix |
| Async MV | Doris 2.x >=2.1.5; Doris 3.x except 3.0.0; Doris 4.x+ | This runtime gate is not a whole-adapter compatibility guarantee. Identifiable source builds are accepted for development testing only |
| VeloDB | No release range has been declared | Release-specific live-cluster verification is pending |
Before production use, run Functional tests against your exact release and topology. Historical results are not a current-release compatibility promise.
Installation
Install the VeloDB-maintained distribution from PyPI:
python -m venv .venv
source .venv/bin/activate
python -m pip install "dbt-for-apache-doris==1.1.0"
dbt --version
[!WARNING] The separate
dbt-doris==1.0.0distribution on PyPI does not contain the code from this repository. Installdbt-for-apache-dorisas shown above.
On Windows, create the environment with py -m venv .venv, activate it using
.venv\Scripts\Activate.ps1, and run the same pip install command.
The adapter declares dbt Core and the MySQL connector as dependencies, so they are installed automatically. You do not need to install dbt Core separately or download a standalone binary.
Quickstart
Add a Doris output to ~/.dbt/profiles.yml. Keep credentials outside version
control; this example reads the password from an environment variable:
doris_demo:
target: dev
outputs:
dev:
type: doris
host: 127.0.0.1
port: 9030
username: root
password: "{{ env_var('DORIS_PASSWORD') }}"
schema: analytics
threads: 4
On Doris, schema is a database; an optional database must match it.
Create a new doris-demo directory with a models subdirectory, then add:
# dbt_project.yml
name: doris_demo
version: 1.0.0
config-version: 2
profile: doris_demo
model-paths: ["models"]
-- models/example.sql
{{ config(materialized='table', replication_num=1) }}
select 1 as id, 'hello from dbt-for-apache-doris' as message
# models/schema.yml
version: 2
models:
- name: example
columns:
- name: id
data_tests: [not_null, unique]
replication_num=1 is only for a local single-BE Quickstart.
export DORIS_PASSWORD='<your-password>'
dbt debug
dbt build
On Windows PowerShell, set the password with
$env:DORIS_PASSWORD = '<your-password>', then run the same dbt commands.
Doris-specific highlights
Incremental strategies
| Strategy | Doris target | Behavior and boundaries |
|---|---|---|
append |
Duplicate Key table | Appends rows with INSERT INTO |
merge |
MOW or MOR Unique Key table | Full-row INSERT INTO upsert using Doris Unique Key semantics; requires unique_key and does not emit SQL MERGE INTO |
insert_overwrite |
Writable Doris table | Whole-table, named-partition, or dynamic-partition INSERT OVERWRITE; unique_key is rejected |
microbatch |
Duplicate Key table with exact RANGE partitions | One named-partition overwrite per dbt Core UTC window; hour/day/month/year windows; static or dynamic partitions; batches run serially |
Without an explicit strategy, unique_key selects merge; otherwise dbt uses
append. delete+insert, partial-column merge, and incremental_predicates
are rejected.
Materialized views
Use dbt's standard materialized_view materialization. The adapter implements
it with Doris Async MV and exposes Doris-specific refresh configuration:
{{ config(
materialized='materialized_view',
refresh_trigger='manual',
wait_for_refresh=true
) }}
select order_date, sum(amount) as sales
from {{ ref('orders') }}
group by order_date
Supported lifecycles include immediate/deferred build, manual/schedule/commit refresh, task waiting, configuration changes, docs, grants, and recovery. Overlapping dbt runs against the same MV target must be serialized, and a dbt wait timeout does not cancel a submitted Doris task.
Known limitations
- Microbatch execution is serial.
- Do not run multiple dbt invocations against the same Snapshot target concurrently; serialize overlapping production jobs in the scheduler.
- Serialize overlapping dbt runs against the same MV target; a dbt wait timeout does not cancel the submitted Doris task.
- Ordinary
tablemodels create Duplicate Key tables. Aggregate Key modeling, secondary indexes, and a complete Doris table abstraction are not implemented. delete+insert, partial-column merge, andincremental_predicatesare not supported.- A complete External Catalog namespace is unsupported.
- SSL configuration, timeout/retry, multi-FE failover, server-side cancellation, and complete query telemetry are not implemented.
- Some Table/View/MV type changes have a short canonical-name availability window rather than a zero-downtime switch.
Development and testing
Install development dependencies, then run local checks:
python -m pip install -r dev-requirements.txt
python -m pip install -e .
make lint
make test-unit
Functional tests need a dedicated non-production cluster. Edit
test/doris_test.env; use an external file for private credentials:
make test
make test DORIS_TEST_CONFIG=/secure/path/doris_test.env
Preflight records live FE/BE versions, checks replication against live BEs, and
requires cross_db_test to be absent. Tests create/drop databases, relations,
users, and grants, so the account needs those permissions. Never use a shared
or production cluster or run Functional sessions concurrently.
python scripts/run_doris_functional_tests.py --preflight-only
python scripts/run_doris_functional_tests.py -- -k snapshot -vv
The runner records evidence about the connected cluster but does not certify a release compatibility matrix.
License
The code is licensed under Apache License 2.0. See the license, notice, and migration provenance.
Metadata
Release files for dbt-for-apache-doris 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dbt_for_apache_doris-1.1.0.tar.gz | 148.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dbt_for_apache_doris-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 230.7 kB
Release files / dbt_for_apache_doris-1.1.0.tar.gz
| Download URL | dbt_for_apache_doris-1.1.0.tar.gz |
|---|---|
| Size | 148.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e68097601b6b2bfc173b9ef128adc3cebda67becabf92973291a75b11e7358b7
|
|
BLAKE2b-256 checksum How to use checksums |
336bda8cb86b5231dc2d25ab7258cd6d64f3cab8a4d4c94bb5eca7439efba762
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.
Transparency logRelease files / dbt_for_apache_doris-1.1.0-py3-none-any.whl
| Download URL | dbt_for_apache_doris-1.1.0-py3-none-any.whl |
|---|---|
| Size | 82.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d83573274c492fe4caa99bff9b05917900097227915d3c80205f843af1af04ab
|
|
BLAKE2b-256 checksum How to use checksums |
2c9b75ba294bd202a29e10ac2968fee03fe35eaf7927f52f36e198ff9868f4d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.
Transparency log