Module 1: Your First Dbt Project

Installing dbt-core and dbt-duckdb

Description

dbt isn't a single package — it's a core (dbt-core, the CLI that compiles and runs your models) plus an adapter for each type of warehouse (dbt-snowflake, dbt-bigquery, dbt-postgres, and the one you're going to use in this guide: dbt-duckdb). dbt-core alone doesn't know how to talk to any specific engine; the adapter is what translates dbt's generic commands (dbt run, dbt test) into your warehouse's specific SQL dialect and manages the real connection. Installing dbt always means installing both: the core and the correct adapter for your case.

This lesson installs both with a single command, inside an isolated Python virtual environment, and verifies the installation is complete with dbt --version — the first dbt command you're going to run in this entire guide, even before you have a project.

Connection to the module. Lesson 3 told you dbt is only the T, no matter what warehouse is behind it. This lesson is where that T becomes real on your machine: by the end, you're going to have the dbt CLI available in your terminal, ready for lesson 5 to use it to inspect a project's anatomy.

An analogy: the engine and the key to the right car

Installing dbt-core is like buying a high-quality generic car: it has an engine, a steering wheel, brakes — everything you need to drive. But that car is useless without a key that starts that specific engine. dbt-duckdb is that key: without it, dbt-core knows how it should talk to a warehouse in general, but has no concrete key that starts DuckDB in particular. If tomorrow Kiosko migrated to Snowflake, you'd swap the key (dbt-snowflake) without swapping the car — the same dbt run, the same .sql models, a different adapter underneath. That separation — generic engine, specific key — is exactly dbt's architecture, and it's the same reason you install the two packages together, never one without the other.

Worked example: real installation, step by step

First, an isolated virtual environment — the same practice you already used in python-for-data-engineering-guide to avoid mixing packages between projects:

python3 -m venv kiosko_env
source kiosko_env/bin/activate   # on Windows: kiosko_env\Scripts\activate

With the environment active (your terminal should show (kiosko_env) at the start of the prompt), install both packages with a single command:

pip install dbt-core dbt-duckdb

What to expect. pip resolves and downloads around sixty packages — dbt-core depends on mature pieces of the Python ecosystem like Jinja2 (the templating engine that makes module 7's macros possible), pydantic (configuration schema validation), and protobuf; none of those is a dependency you need to understand right now. The final line of the install confirms the two packages you actually care about:

Successfully installed Babel-2.18.0 MarkupSafe-3.0.3 agate-1.9.1 annotated-types-0.8.0 attrs-26.1.0
charset_normalizer-3.5.0 click-8.4.2 colorama-0.4.6 daff-1.4.2 dbt-adapters-1.24.5 dbt-common-1.39.0
dbt-core-1.12.2 dbt-core-experimental-parser-2.0.0b1 dbt-duckdb-1.11.0 dbt-extractor-0.6.0
dbt-protos-1.0.541 deepdiff-8.6.2 duckdb-1.5.5 idna-3.18 importlib-metadata-9.0.0 isodate-0.7.2
jinja2-3.1.6 jsonschema-4.26.0 jsonschema-specifications-2025.9.1 leather-0.4.1 mashumaro-3.17
metricflow-0.211.0 more-itertools-10.8.0 msgpack-1.2.1 networkx-3.6.1 opentelemetry-api-1.44.0
orderly-set-5.5.0 packaging-26.3 parsedatetime-2.6 pathspec-1.0.4 protobuf-6.33.6 pydantic-2.13.4
pydantic-core-2.46.4 python-dateutil-2.9.0.post0 python-dotenv-1.2.2 python-slugify-8.0.4
pytimeparse-1.1.8 pytz-2026.3.post1 pyyaml-6.0.3 rapidfuzz-3.14.5 referencing-0.37.0 requests-2.34.2
rpds-py-2026.6.3 six-1.17.0 snowplow-tracker-1.1.0 sqlglot-30.17.0 sqlparse-0.5.5 tabulate-0.10.0
text-unidecode-1.3 typing-extensions-4.16.0 typing-inspection-0.4.4 urllib3-2.7.0 zipp-4.1.0

Look for only two names in that long list: dbt-core-1.12.2 and dbt-duckdb-1.11.0. Those are, as of this guide's writing, the current versions — dbt-duckdb published its 1.11.0 just a few days earlier, and dbt-core is on its 1.12 branch. You'll probably install equal or slightly newer versions; that's normal and expected — dbt-core and dbt-duckdb keep receiving releases — and it shouldn't change anything you learn in this guide.

Now, the real verification — the command that confirms both pieces got installed and are compatible with each other:

dbt --version

What to expect.

Core:
  - installed: 1.12.2
  - latest:    1.12.2 - Up to date!

Plugins:
  - duckdb: 1.11.0 - Up to date!

Two blocks, not one: Core is dbt-core, the generic CLI. Plugins lists every adapter installed in your environment — in your case, only duckdb. If you ever work on a project with several adapters installed at once (uncommon, but possible), you'd see several lines under Plugins. The Up to date! message is informational: dbt --version silently checks whether a newer published version exists and tells you — it doesn't fail or block anything if you're not.

Diagram: core + adapter, the complete architecture

┌─────────────────────────────────────────────────────────┐
│  dbt-core (the CLI: dbt run, dbt test, dbt debug, ...)    │
│  - parses your .sql and .yml files                        │
│  - compiles Jinja into plain SQL                           │
│  - computes the execution order (the DAG, module 3)        │
│  - does NOT know how to talk to any warehouse on its own    │
└───────────────────────┬───────────────────────────────────┘
                         │  uses
                         v
┌─────────────────────────────────────────────────────────┐
│  dbt-duckdb (the adapter)                                  │
│  - translates the compiled SQL into DuckDB's dialect         │
│  - opens and maintains the connection to kiosko.duckdb        │
│  - knows how to read CSV/Parquet/JSON directly (module 2)      │
└─────────────────────────────────────────────────────────┘

Going deeper: why a virtual environment, not a global install

You already saw virtual environments in python-for-data-engineering-guide, but it's worth repeating why they matter specifically here: dbt-core pins exact versions of its dependencies (Jinja2, pydantic, protobuf) to guarantee the compiler behaves predictably. If you install dbt-core globally, any other Python project on your machine that depends on a different version of those same libraries can conflict — a classic error where installing something new silently breaks something old. A per-project virtual environment (kiosko_env, in this case) fully isolates those dependencies: what you install here doesn't affect any other project on your machine, and vice versa.

Common mistakes

CERTIFICATE_VERIFY_FAILED when running pip install. What happens: on macOS, especially with the official python.org installer, pip can fail with an SSL error like [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate when trying to download one of dbt's packages. Why it happens: the python.org installer doesn't always automatically link to the operating system's root certificate store, so Python can't verify the identity of PyPI's servers. How to spot it: the error message explicitly mentions CERTIFICATE_VERIFY_FAILED or SSL, almost always while downloading a specific package. How to fix it: on macOS with the official installer, run the script Python itself includes for this — /Applications/Python\ 3.1x/Install\ Certificates.command (adjust the version number) — and try pip install again. If you use another Python distribution (Homebrew, for example) where that script doesn't exist, install certifi (pip install certifi) and export SSL_CERT_FILE=$(python3 -m certifi) before repeating the install.

Installing dbt-core with no adapter, and getting confused by the error later. What happens: someone runs only pip install dbt-core, without dbt-duckdb, and later — in lesson 6, when trying dbt debug — gets an error saying their profiles.yml's type: duckdb isn't recognized. Why it happens: it's easy to think dbt-core "comes with everything included," when in reality every adapter is a completely separate PyPI package that has to be installed on purpose. How to spot it: if dbt --version shows no lines under Plugins, you have no adapter installed, no matter how recent your dbt-core is. How to fix it: pip install dbt-duckdb separately (or, better, both together from the start, as this lesson's worked example does) and run dbt --version again to confirm duckdb shows up under Plugins.

Forgetting to activate the virtual environment in a new terminal. What happens: someone installs everything correctly, closes the terminal, reopens it the next day, runs dbt --version, and gets command not found: dbt. Why it happens: activating a virtual environment (source kiosko_env/bin/activate) is a setting for the current terminal session — it doesn't persist between sessions or activate on its own. How to spot it: if your prompt doesn't show (kiosko_env) at the start, the environment isn't active, no matter that you activated it yesterday. How to fix it: source kiosko_env/bin/activate (adjusting the path if you created the environment in a different folder) at the start of every terminal session where you're going to work on Kiosko's project — you're going to repeat this step in every lesson that follows.

Exercises

Exercise 1 — Diagnose an incomplete dbt --version. A teammate runs dbt --version and gets only this:

Core:
  - installed: 1.12.2
  - latest:    1.12.2 - Up to date!

Plugins:
  No adapters installed

Exactly which command are they missing?

See solution

They're missing pip install dbt-duckdb. dbt-core installed correctly (the Core section confirms it), but no adapter is present — the Plugins section is empty. Without an adapter, dbt-core has no "key" to start any specific warehouse, not even DuckDB; commands that depend on a real connection (dbt debug, dbt run) would fail until they install the right adapter.

Exercise 2 — Verify your own installation. If you already have dbt installed (or after installing it following this lesson's worked example), run dbt --version in your own terminal and write down exactly what version of Core and of Plugins: duckdb shows up for you.

See solution

There's no single correct answer here — the goal is for you to confirm, with your own literal output, that you have both pieces installed. If your version of dbt-core or dbt-duckdb is newer than 1.12.2 / 1.11.0 (the ones this guide uses), that's expected and shouldn't break any example in the lessons that follow — dbt keeps backward compatibility within the same major version branch. If instead the Plugins section shows up empty, repeat Exercise 1: you're missing pip install dbt-duckdb.

Exercise 3 — Argue why the command's order doesn't matter. This lesson's worked example installs with pip install dbt-core dbt-duckdb, in that order. Would anything change if you installed it as pip install dbt-duckdb dbt-core, in reverse order? Justify it using what you know about the core + adapter architecture.

See solution

Nothing changes. pip install with several packages on the same line resolves all dependencies declared by both packages before installing anything, no matter the order you wrote them in the command — dbt-duckdb declares dbt-core as one of its dependencies (it needs the core to work), so pip is going to install it anyway even if you hadn't named it explicitly. The order in the command is a reading convenience for you, not a sequencing instruction for pip.

Summary and next step

In this lesson you installed dbt-core 1.12.2 and dbt-duckdb 1.11.0 — the generic CLI and the DuckDB-specific adapter — inside an isolated virtual environment, and verified the complete installation with dbt --version. You saw why dbt always installs in two pieces — core and adapter — and what to do if pip install fails with an SSL certificate error, a real error worth recognizing if it happens to you.

Before moving on you should be able to: explain the difference between dbt-core and an adapter like dbt-duckdb; and read dbt --version's output to confirm both pieces are installed and compatible.

With dbt really installed on your machine, lesson 5 opens your first project: the minimal anatomy of a dbt folder — which files are required, which are generated, and what each one means — before writing a single line of SQL.

Resources

  • dbt Developer Hub — "Quickstart for dbt Core using DuckDB," the official guide that confirms the pip install dbt-duckdb command and the virtual-environment install flow. docs.getdbt.com/guides/duckdb. In English.
  • dbt-duckdb — PyPI, the package's official page confirming the current version (1.11.0), the Apache-2.0 license, and the Python >= 3.10 requirement. pypi.org/project/dbt-duckdb. In English.
  • Python — official venv documentation, the standard module used in this lesson to create the kiosko_env virtual environment. docs.python.org/3/library/venv.html. In English.