You want to update models without taking production dashboards down — the practical answer is a Blue/Green deployment that swaps schemas. dbt can split schemas per target, which makes it a great fit for this pattern.
This article centers on the portable Router-schema + Blue/Green-schema approach. We cover the implementation, operational tips, and points the exam likes to test. Everything is based on stable dbt features (targets, selectors, defer, state) and the general behavior of major DWHs.
dbt can swap schemas per profile target, making it easy to run the same set of models side-by-side in Blue (current) and Green (candidate). Build new versions in Green, validate, then switch references — and the impact on readers (BI, apps) stays minimal.
Combine dbt's state selectors with defer to rebuild only changed nodes into Green while resolving unchanged dependencies from Blue. You get both speed and safety during the cutover.
A practical approach is to separate the physical Blue/Green schemas from a stable consumer-facing schema (the Router schema). Create views in the Router schema and redirect them to either Blue or Green. CREATE OR REPLACE on a view is metadata-level on most DWHs, so a single-object swap is fast and atomic.
Note that bulk-swapping multiple views at the exact same instant depends on what your DWH supports. For availability-oriented analytics workloads that do not require strict simultaneity, sequential view replacement with schema compatibility is the realistic operating model.
Architecture of Blue/Green with a Router schema
Below is the standard flow: incremental build, validation, then flip the Router to Green. Using dbt's defer and state, unchanged models are resolved from the existing Blue environment while only changed nodes are built into Green.
The production cutover is complete once you recreate the Router-schema views to point at Green. If anything goes wrong, use the same procedure to point them back at Blue.
Define two targets with fixed Blue/Green schema names. Perform the switch by recreating all Router-schema views via a run-operation. Use state:modified+ as your selector and defer to resolve unchanged nodes from the current environment.
Below is a minimal example. In real environments, add permission management (GRANT USAGE/SELECT), per-model exceptions, async monitoring, and so on.
Example profiles.yml and publish_router macro
# profiles.yml(抜粋)
my_project:
target: blue
outputs:
blue:
type: snowflake # 例。BigQuery/Databricks等でも同様にtargetでスキーマ分離
account: <account>
user: <user>
password: <password>
role: <role>
database: ANALYTICS
warehouse: TRANSFORMING
schema: analytics_blue
green:
type: snowflake
account: <account>
user: <user>
password: <password>
role: <role>
database: ANALYTICS
warehouse: TRANSFORMING
schema: analytics_green
-- macros/publish_router.sql
{% macro publish_router(color='green', router_schema='analytics', models=None) %}
{# colorは'blue'または'green' #}
{% set db = target.database %}
{% set base_schema = 'analytics_' ~ color %}
{# 対象モデルの解決 #}
{% if models is not none %}
{% set selected = [] %}
{% for m in models %}
{% do selected.append(graph.nodes['model.' ~ project_name ~ '.' ~ m]) %}
{% endfor %}
{% else %}
{% set selected = graph.nodes.values() | selectattr('resource_type', 'equalto', 'model') | list %}
{% endif %}
{# ビューの再作成(単体オブジェクトは原子的に置換) #}
{% for node in selected %}
{% set src = adapter.quote(db) ~ '.' ~ adapter.quote(base_schema) ~ '.' ~ adapter.quote(node.alias) %}
{% set dst = adapter.quote(db) ~ '.' ~ adapter.quote(router_schema) ~ '.' ~ adapter.quote(node.alias) %}
{% do run_query('create or replace view ' ~ dst ~ ' as select * from ' ~ src) %}
{% endfor %}
{% endmacro %}
# selectors.yml(差分ビルド用の例)
selectors:
- name: ci_modified
definition:
union:
- method: state
value: modified+
children: true
- method: fqn
value: "tests"Beyond per-model tests, include metric-consistency checks (e.g., day-over-day deltas), row counts, primary-key duplicates, and row-count/sum diffs across critical tables. That catches failures earlier. Immediately after the Router switch, increase monitoring and treat the next 5-15 minutes as a focus window.
Rollback is instant — just re-run publish_router against Blue. The physical schemas remain intact, so you can investigate the cause and rebuild Green in parallel. Pair this with a cleanup process (using tags or metadata) that drops old schemas after a retention window.
The Analytics Engineer exam often tests environment isolation, incremental builds (state:modified+), the meaning of defer, and rollback strategies. In a Blue/Green context, remember that view replacement is generally atomic, but truly simultaneous swaps across multiple objects depend on the engine.
Compare the stable behavior of major cloud DWHs. The key point: if you want a portable operation, the Router-view approach tends to be the common-denominator solution.
| Capability / Behavior | Snowflake | BigQuery | Databricks (Delta) |
|---|---|---|---|
| View CREATE OR REPLACE | Atomic replacement (metadata update); typically fast | Atomic replacement; metadata operation is fast | Atomic replacement via metadata update |
| Schema (dataset) swap | No schema SWAP (DB-level SWAP and table SWAP are offered) | No dataset swap | No schema swap |
| Atomic table swap | ALTER TABLE ... SWAP WITH is available | Use CREATE OR REPLACE TABLE or snapshot copy | CREATE OR REPLACE TABLE (atomic via Delta transactions) |
| Clone / Time Travel | Zero-copy CLONE enables fast recovery | Table snapshots enable recovery | Delta Time Travel enables recovery |
| Permission inheritance | GRANTs on views are independent; watch for grant loss on recreation | Re-grants may be required after view recreation | Be careful preserving grants on view recreation (script this) |
Analytics Engineer
問題 1
You are implementing a Blue/Green deployment with dbt. The current environment is analytics_blue, the candidate is analytics_green, and consumers read from the analytics schema. You want to build only changed models into the candidate, then cut over with no downtime and roll back instantly after tests pass. Which procedure fits best?
正解: A
Building only changed nodes into the candidate schema is exactly what state:modified+ and --defer are for, and republishing the Router schema (analytics) via CREATE OR REPLACE on its views minimizes downtime. On failure, pointing the views back at Blue gives an instant recovery.
Do I need to redo GRANT permissions on every switchover?
If you lock down GRANTs on the views under the Router schema, you only swap the view body (the referenced relation) during cutover, so no extra grant work is usually required. However, some DWHs drop privileges on CREATE OR REPLACE, so it is safer to automate post-recreation permission verification and re-granting.
Can I switch all views at the exact same instant?
Replacing a single view is atomic, but truly simultaneous replacement across multiple objects depends on engine capabilities. Most teams keep schemas compatible and rely on short sequential replacements plus monitoring to maintain availability. If strict simultaneity is required, consider engine-specific swap features or controlled publish ordering.
Are --defer and state:modified+ safe to use in production?
Yes. Point --state at the latest production artifacts (manifest.json / runner_artifacts) and use --defer to resolve unchanged upstream nodes from production. You can then rebuild only the changed nodes into the candidate environment without destroying existing relations, which pairs well with Blue/Green.
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...