Add dbt model
Add a new dbt model (staging, intermediate, or marts) to an existing MDS deployment. Invoke when the user wants to transform raw data, build an analytics table, or expose a new metric in BigQuery.From its SKILL.md
npx -y skills add pol-cc/agentic-data-engineer --skill add-dbt-modelAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 2 commands, including `dbt run --select <model>` and 1 more.
SKILL.md
5.0 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it
add-dbt-model
Status: v0.10.0 (pre-test) — conventions + templates complete, with incremental-by-default for fact/event marts on BigQuery (cost control). Conventions and decision-tree references written; copy-paste templates (staging, marts dimension, marts incremental fact, schema, sources) included plus the
incremental-and-cost.mdreference; the Phase A–D playbook (classify → write → run/verify → commit) is in place.
What this skill does
Adds a new dbt model to the client's dbt project. Decides where the model belongs (staging / intermediate / marts) based on what the user describes, writes the SQL, adds tests, and runs it once to verify before committing.
Preflight
if [ ! -f .agentic-data-engineer.json ]; then
echo "[abort] not a managed MDS deployment"
exit 1
fi
# Confirm dbt is configured in this stack
jq -e '.stack.transform == "dbt_vps"' .agentic-data-engineer.json > /dev/null || {
echo "[abort] this MDS doesn't have dbt configured"
echo "Phase 2 of create-mds adds dbt — run that first"
exit 1
}
Playbook outline
Phase A — Classify the model
Ask the user what they want to compute. Then decide:
| Layer | When |
|---|---|
staging (stg_<source>_<table>) | One-to-one with a raw source table, applies cleanup (rename columns, cast types, filter junk rows). One staging model per raw table. |
intermediate (int_<concept>) | Reusable logic that several marts will consume (e.g. int_orders_with_customer). Not exposed to end users. |
marts (analytics-ready, plain names like orders, revenue_monthly) | The deliverable. End users and BI tools query these. |
See references/staging-vs-marts.md and references/dbt-naming-conventions.md.
Materialization is a cost decision on BigQuery (bills by bytes scanned). Default by layer: staging = view; dimensions / small reports = table; fact/event marts = incremental (partitioned + clustered, insert_overwrite). A full-refresh table on a growing fact re-scans all history every run — the surprise-bill risk this default prevents. See references/incremental-and-cost.md.
Phase B — Write the model
- SSH to the VPS, locate the dbt project.
- Create the SQL file in the right folder.
- Write the
SELECTwith explicit column lists (neverSELECT *in marts). - Add a
schema.ymlentry with tests (not_null,uniquewhere applicable,accepted_valuesfor known categories).
Phase C — Run and verify
dbt run --select <model>in the venv on the VPS.dbt test --select <model>.- Spot-check the resulting table in BigQuery (
bq queryorSELECT * LIMIT 10).
Phase D — Commit
- Push to the client repo.
- Update marker history.
References
Conventions (complete):
references/dbt-naming-conventions.md— file/model/column naming, SQL style, tests pattern, canonical model shapesreferences/staging-vs-marts.md— decision tree for which layer a model belongs inreferences/incremental-and-cost.md— BigQuery cost control: when to go incremental, partition/cluster choice,maximum_bytes_billed, the GCP budget alert backstop, and the light cross-db convention (prefer dbt macros, flatten structs early — noadapter.dispatchframework)
Templates (complete) — copy into the client's dbt project and fill the <PLACEHOLDER> markers:
templates/staging.sql.template— canonical staging model:viewmaterialization,source+renamedCTEs, explicit casts, ingest-tool-agnostic load metadata (dlt's_dlt_load_id→load_id, join_dlt_loadsfor the timestamp; Airbyte legacy_airbyte_extracted_at→loaded_at),where <pk> is not nulltemplates/marts.sql.template— DIMENSION / small-report mart:tablematerialization, one CTE perref()input, ajoinedCTE, explicit final select. Heavily commented on when to usetable(dim) vsincremental(fact)templates/marts_incremental.sql.template— FACT / event mart (BigQuery default):incremental+insert_overwrite+partition_by+cluster_by+on_schema_change, with theis_incremental()look-back guardtemplates/schema.yml.template— model docs + tests (not_null/uniquePK,not_nullFK,accepted_valuesenum, optional monetary check) plus optional incremental-fact guards (partitionnot_null, recency, row-count)templates/sources.yml.template— rawsources:declaration (database<project>, schemaraw_<source>, freshness warn 26h / error 50h,loaded_at_field)
What ships with it: 8 files
39.2 KB alongside SKILL.md
references/
- dbt-naming-conventions.md7.4 KB
- incremental-and-cost.md9.0 KB
- staging-vs-marts.md5.4 KB
templates/
- marts_incremental.sql.template5.1 KB
- marts.sql.template3.5 KB
- schema.yml.template3.5 KB
- sources.yml.template2.0 KB
- staging.sql.template3.3 KB