dbt_project.yml is the blueprint for your entire project. It heavily shapes runtime behavior: default model materialization, schema naming, path layout, macro dispatch strategy, and more.
This article focuses on stable concepts that directly map to Analytics Engineer exam prep. We avoid version-specific behavior and follow the general assumptions found in the official documentation.
dbt_project.yml declares project metadata and default settings. At minimum, define the project name, version, the profile name to use, and the config file format version (commonly 2).
Path keys (models, seeds, snapshots, tests, macros, etc.) have defaults and can be omitted, but it is safer to set them explicitly for team readability and CI stability.
| Key | Example | Notes |
|---|---|---|
| name | my_dbt_proj | Used inside unique_id. Renaming has wide-reaching impact |
| version | 1.0.0 | Logical project version. Also meaningful when distributing as a package |
| profile | warehouse_default | Maps to a profiles.yml connection. The target switches per environment |
| config-version | 2 | The current config format. Use 2 |
| model-paths | ['models'] | Optional (has a default). Being explicit improves readability |
From dbt_project.yml to a final relation name
Minimal to basic dbt_project.yml example
name: my_dbt_proj
version: 1.0.0
config-version: 2
profile: warehouse_default
model-paths: ["models"]
seed-paths: ["seeds"]
snapshot-paths: ["snapshots"]
test-paths: ["tests"]
macro-paths: ["macros"]
require-dbt-version: ">=1.3.0"
quoting:
database: false
schema: false
identifier: false
models:
my_dbt_proj:
+materialized: view
Naming conventions directly impact query readability and operational cost. Keep model names (file names), aliases, and schemas consistent, and apply per-directory defaults (materialized, schema, etc.) to keep things manageable.
Centralizing defaults for seeds and snapshots in dbt_project.yml blocks prevents policy drift.
| Resource | Default path key | Default / placement | Common overrides (examples) |
|---|---|---|---|
| models | model-paths | view (default) | +materialized, +schema, +alias, +database, tags |
| seeds | seed-paths | Loaded as a table | delimiter, quote_columns, column_types, +schema, +database |
| snapshots | snapshot-paths | snapshot tables | target_schema, target_database |
| tests | test-paths | Generic / singular test definitions | severity, store_failures, +schema (where applicable) |
Recommended directory layout (example)
project_root/
models/
staging/
intermediate/
marts/
seeds/
snapshots/
tests/
macros/
target/ (生成物)
dbt_packages/ (依存パッケージ)Example paths and naming conventions (project defaults)
models:
my_dbt_proj:
+materialized: view
staging:
+schema: stg
+tags: [staging]
marts:
+materialized: table
+schema: marts
+tags: [prod]
seeds:
my_dbt_proj:
+schema: seed
quote_columns: true
delimiter: ","
snapshots:
my_dbt_proj:
target_schema: snap
dbt settings have different precedence depending on where they are written. Precedence and the alias/schema resolution order are favorite exam targets.
The basic principle: more local definitions win, and explicit CLI flags take the highest priority.
| Layer | Example | When to use |
|---|---|---|
| CLI | dbt run --full-refresh | Temporary overrides; CI/CD branches, etc. |
| Inside a resource | config(materialized='table') inside models/.../model.sql | Special-case a single model |
| Project | The models: block in dbt_project.yml | Set defaults per directory |
| Package | Settings from a dependent package | Externally provided defaults (overridable) |
| Default | e.g., materialized = view | Fallback when nothing is specified |
Visualizing config precedence as terraced layers
A sample showing precedence differences
# models/marts/orders.sql
{{ config(materialized='table', alias='fct_orders') }}
select * from {{ ref('int_orders') }}
# dbt_project.yml(抜粋)
models:
my_dbt_proj:
marts:
+materialized: view # ← リソース内 config がこれを上書き
+schema: marts
Schemas are decided by target (the target setting in profiles.yml), the project-side +schema, and the generate_schema_name macro that ties them together. With the default implementation, providing +schema typically appends it onto target.schema.
Decide explicitly as a team between suffix-append vs. full-replace, and override the macro if needed to prevent incidents.
| Approach | Characteristics | Caveats / pros |
|---|---|---|
| Default (suffix append) | target.schema + '_' + custom | Custom values can be shared across prod/dev without collision |
| Full replacement | Returns custom as-is | When migrating, watch for conflicts with existing schema names |
| Environment suffix | Attach env on the target side | dbt_project.yml stays simple; profiles.yml management becomes critical |
Examples of combining environment and custom schema
target.schema = analytics
+schema = stg
既定: analytics_stg
完全置換: stg
環境サフィックス例: analytics_dev_stgOverriding generate_schema_name (full replacement example)
{% macro generate_schema_name(custom_schema_name, node) %}
{# 完全置換:custom_schema_name があればそれを使い、なければ target.schema #}
{% if custom_schema_name is not none %}
{{ custom_schema_name }}
{% else %}
{{ target.schema }}
{% endif %}
{% endmacro %}
# dbt_project.yml(例)
models:
my_dbt_proj:
staging:
+schema: stg
vars is a place to store parameters referenced from macros and models. dispatch controls the search order for macro resolution, helping you coexist with adapters and your own packages.
For compatibility and safety, pin the runtime version with require-dbt-version and make quoting, on-run-*, and clean-targets explicit.
| Key | Purpose | Common exam targets |
|---|---|---|
| dispatch | Control macro search order | Tests the dbt → custom search order |
| vars | Inject values into macros/models | Combination with env_var and default values |
| require-dbt-version | Pin the runtime version | Meaning of range notation (>=, <) |
| quoting | Control identifier quoting | Independent for identifier / schema / database |
| on-run-start/end | Pre/post-run hooks | Automating audit tables and permission setup |
Macro resolution dispatch order
Examples of extension-related settings
dispatch:
- macro_namespace: dbt
search_order: [my_pkg, dbt]
vars:
country: "JP"
run_ts: "{{ var('override_ts', env_var('RUN_TS', '1970-01-01')) }}"
require-dbt-version: ">=1.3.0,<2.0.0"
quoting:
database: false
schema: false
identifier: false
on-run-start:
- "{{ log('Run started at ' ~ run_started_at, info=True) }}"
clean-targets: ["target", "dbt_packages"]
packages-install-path: "dbt_packages"
Frequent Analytics Engineer exam topics include config precedence, schema/identifier naming, and the default-vs-override relationship for seeds and snapshots. Use the checks below to close knowledge gaps.
The relationship between alias and ref, the default behavior of +schema with generate_schema_name, and the default for seeds' quote_columns are especially easy to confuse.
| Common misconception | Correct understanding | Basis / hint |
|---|---|---|
| Changing alias also changes the ref name | ref resolves by node name; alias only affects the physical name | Official reference resolution is unique_id-based |
| +schema replaces target.schema | By default it is usually appended onto target.schema | Default implementation of generate_schema_name |
| Without explicit settings, seed columns are not quoted | Columns are quoted by default (true on most adapters) | Make it explicit at the project level |
A rough picture of the execution flow
Practical settings examples for seeds and tests
seeds:
my_dbt_proj:
+schema: seed
quote_columns: true
delimiter: ","
column_types:
id: integer
amount: numeric
tests:
+severity: warn
+store_failures: true
+schema: test_audit
Analytics Engineer
問題 1
If profiles.yml sets target.schema = analytics and dbt_project.yml's models: block sets +schema: stg, which schema will the model be created in when using the default generate_schema_name implementation?
正解: C
The default generate_schema_name commonly appends a custom schema onto target.schema, yielding analytics_stg. Override the macro if you need full replacement instead.
Is it safe to rename the name field in dbt_project.yml later?
Technically yes, but the unique_id (resource_type.package.name) changes, which affects artifact integrations, test selectors, and documentation generation. Plan renames in production carefully.
If I set an alias, do I need to call ref() with the alias name?
No. ref resolves by node (model file) name. alias only changes the physical table/view name.
How should I handle column quoting and case sensitivity for seeds?
quote_columns commonly defaults to true. Since identifier rules depend on the adapter, make quote_columns and your column-name normalization policy explicit at the project level.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
dbt Models: SQL-Defined Transformation Units (2026)
Model fundamentals — SELECT-based definitions, naming, refs,...
dbt Analytics Engineering Exam: Complete Guide (2026)
Pass the AE Certification — scope, weighting, sample questio...
dbt Cloud vs dbt Core: Feature & Cost Comparison (2026)
Honest comparison of dbt Cloud vs. dbt Core — IDE, scheduler...
dbt Project Structure: models/seeds/macros Layout (2026)
Recommended dbt project layout — models, seeds, macros, snap...
dbt_project.yml Explained: Every Config (2026)
Every dbt_project.yml setting that matters — paths, vars, ma...