altimate-code 0.4.9 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +22 -60
- package/package.json +54 -14
- package/postinstall.mjs +35 -0
- package/skills/cost-report/SKILL.md +134 -0
- package/skills/data-viz/SKILL.md +135 -0
- package/skills/data-viz/references/component-guide.md +394 -0
- package/skills/dbt-analyze/SKILL.md +130 -0
- package/skills/dbt-analyze/references/altimate-dbt-commands.md +66 -0
- package/skills/dbt-analyze/references/lineage-interpretation.md +58 -0
- package/skills/dbt-develop/SKILL.md +151 -0
- package/skills/dbt-develop/references/altimate-dbt-commands.md +66 -0
- package/skills/dbt-develop/references/common-mistakes.md +49 -0
- package/skills/dbt-develop/references/incremental-strategies.md +118 -0
- package/skills/dbt-develop/references/layer-patterns.md +158 -0
- package/skills/dbt-develop/references/medallion-architecture.md +125 -0
- package/skills/dbt-develop/references/yaml-generation.md +90 -0
- package/skills/dbt-docs/SKILL.md +99 -0
- package/skills/dbt-docs/references/altimate-dbt-commands.md +66 -0
- package/skills/dbt-docs/references/documentation-standards.md +94 -0
- package/skills/dbt-test/SKILL.md +121 -0
- package/skills/dbt-test/references/altimate-dbt-commands.md +66 -0
- package/skills/dbt-test/references/custom-tests.md +59 -0
- package/skills/dbt-test/references/schema-test-patterns.md +103 -0
- package/skills/dbt-test/references/unit-test-guide.md +121 -0
- package/skills/dbt-troubleshoot/SKILL.md +187 -0
- package/skills/dbt-troubleshoot/references/altimate-dbt-commands.md +66 -0
- package/skills/dbt-troubleshoot/references/compilation-errors.md +57 -0
- package/skills/dbt-troubleshoot/references/runtime-errors.md +71 -0
- package/skills/dbt-troubleshoot/references/test-failures.md +95 -0
- package/skills/lineage-diff/SKILL.md +64 -0
- package/skills/pii-audit/SKILL.md +117 -0
- package/skills/query-optimize/SKILL.md +86 -0
- package/skills/schema-migration/SKILL.md +119 -0
- package/skills/sql-review/SKILL.md +118 -0
- package/skills/sql-translate/SKILL.md +68 -0
- package/skills/teach/SKILL.md +54 -0
- package/skills/train/SKILL.md +51 -0
- package/skills/training-status/SKILL.md +45 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# YAML Config Generation
|
|
2
|
+
|
|
3
|
+
## sources.yml — Define Raw Data Sources
|
|
4
|
+
|
|
5
|
+
Generate from warehouse metadata using:
|
|
6
|
+
```bash
|
|
7
|
+
altimate-dbt columns-source --source <source_name> --table <table_name>
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Template:
|
|
11
|
+
```yaml
|
|
12
|
+
version: 2
|
|
13
|
+
|
|
14
|
+
sources:
|
|
15
|
+
- name: raw_stripe
|
|
16
|
+
description: Raw Stripe payment data
|
|
17
|
+
database: raw
|
|
18
|
+
schema: stripe
|
|
19
|
+
tables:
|
|
20
|
+
- name: payments
|
|
21
|
+
description: All payment transactions
|
|
22
|
+
columns:
|
|
23
|
+
- name: payment_id
|
|
24
|
+
description: Primary key
|
|
25
|
+
tests:
|
|
26
|
+
- unique
|
|
27
|
+
- not_null
|
|
28
|
+
- name: amount
|
|
29
|
+
description: Payment amount in cents
|
|
30
|
+
- name: created_at
|
|
31
|
+
description: Payment creation timestamp
|
|
32
|
+
tests:
|
|
33
|
+
- not_null
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## schema.yml — Model Documentation and Tests
|
|
37
|
+
|
|
38
|
+
Generate after building a model using:
|
|
39
|
+
```bash
|
|
40
|
+
altimate-dbt columns --model <model_name>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Template:
|
|
44
|
+
```yaml
|
|
45
|
+
version: 2
|
|
46
|
+
|
|
47
|
+
models:
|
|
48
|
+
- name: stg_stripe__payments
|
|
49
|
+
description: Staged Stripe payments with renamed columns and type casts
|
|
50
|
+
columns:
|
|
51
|
+
- name: payment_id
|
|
52
|
+
description: Primary key from source
|
|
53
|
+
tests:
|
|
54
|
+
- unique
|
|
55
|
+
- not_null
|
|
56
|
+
- name: amount_dollars
|
|
57
|
+
description: Payment amount converted to dollars
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Column Pattern Heuristics
|
|
61
|
+
|
|
62
|
+
When auto-generating YAML, infer descriptions and tests from column names:
|
|
63
|
+
|
|
64
|
+
| Pattern | Description Template | Auto-Tests |
|
|
65
|
+
|---------|---------------------|------------|
|
|
66
|
+
| `*_id` | "Foreign key to {table}" or "Primary key" | `unique`, `not_null` |
|
|
67
|
+
| `*_at`, `*_date`, `*_timestamp` | "Timestamp of {event}" | `not_null` |
|
|
68
|
+
| `*_amount`, `*_price`, `*_cost` | "Monetary value" | `not_null` |
|
|
69
|
+
| `is_*`, `has_*` | "Boolean flag for {condition}" | `accepted_values: [true, false]` |
|
|
70
|
+
| `*_type`, `*_status`, `*_category` | "Categorical" | `accepted_values` (if inferable) |
|
|
71
|
+
| `*_count`, `*_total`, `*_sum` | "Aggregated count/total" | — |
|
|
72
|
+
| `*_name`, `*_title`, `*_label` | "Human-readable name" | — |
|
|
73
|
+
|
|
74
|
+
## File Naming Conventions
|
|
75
|
+
|
|
76
|
+
| Convention | Example |
|
|
77
|
+
|-----------|---------|
|
|
78
|
+
| Sources | `_<source>__sources.yml` |
|
|
79
|
+
| Model schema | `_<model>__models.yml` or `schema.yml` |
|
|
80
|
+
| Properties | `_<model>__models.yml` |
|
|
81
|
+
|
|
82
|
+
Match whatever convention the project already uses. Check existing `.yml` files in the same directory.
|
|
83
|
+
|
|
84
|
+
## Merging with Existing YAML
|
|
85
|
+
|
|
86
|
+
When YAML files already exist:
|
|
87
|
+
1. Read the existing file first
|
|
88
|
+
2. Add new entries without duplicating existing ones
|
|
89
|
+
3. Preserve human-written descriptions
|
|
90
|
+
4. Use `edit` tool (not `write`) to merge
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dbt-docs
|
|
3
|
+
description: Document dbt models and columns in schema.yml with business context — model descriptions, column definitions, and doc blocks. Use when adding or improving documentation for discoverability. Powered by altimate-dbt.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dbt Documentation
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
**Agent:** builder or migrator (requires file write access)
|
|
10
|
+
**Tools used:** bash (runs `altimate-dbt` commands), read, glob, write, edit
|
|
11
|
+
|
|
12
|
+
## When to Use This Skill
|
|
13
|
+
|
|
14
|
+
**Use when the user wants to:**
|
|
15
|
+
- Add or improve model descriptions in schema.yml
|
|
16
|
+
- Write column-level descriptions with business context
|
|
17
|
+
- Create shared doc blocks for reusable definitions
|
|
18
|
+
- Improve dbt docs site content
|
|
19
|
+
|
|
20
|
+
**Do NOT use for:**
|
|
21
|
+
- Adding tests → use `dbt-test`
|
|
22
|
+
- Creating new models → use `dbt-develop`
|
|
23
|
+
- Generating sources.yml from scratch → use `dbt-develop`
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
### 1. Understand the Model
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
altimate-dbt columns --model <name> # what columns exist
|
|
31
|
+
altimate-dbt parents --model <name> # what feeds this model
|
|
32
|
+
altimate-dbt children --model <name> # who consumes it
|
|
33
|
+
altimate-dbt compile --model <name> # see the rendered SQL
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Read the model SQL to understand the transformations:
|
|
37
|
+
```bash
|
|
38
|
+
glob models/**/<name>.sql
|
|
39
|
+
read <model_file>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Read Existing Documentation
|
|
43
|
+
|
|
44
|
+
Check what's already documented:
|
|
45
|
+
```bash
|
|
46
|
+
glob models/**/*schema*.yml models/**/*_models.yml
|
|
47
|
+
read <yaml_file>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 3. Write Documentation
|
|
51
|
+
|
|
52
|
+
See [references/documentation-standards.md](references/documentation-standards.md) for quality guidelines.
|
|
53
|
+
|
|
54
|
+
#### Model-Level Description
|
|
55
|
+
Cover: **What** (business entity), **Why** (use case), **How** (key transforms), **When** (materialization).
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
- name: fct_daily_revenue
|
|
59
|
+
description: >
|
|
60
|
+
Daily revenue aggregation by product category. Joins staged orders with
|
|
61
|
+
product dimensions and calculates gross/net revenue. Materialized as
|
|
62
|
+
incremental with unique key on (date_day, category_id). Used by the
|
|
63
|
+
finance team for daily P&L reporting.
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### Column-Level Description
|
|
67
|
+
Describe business meaning, derivation formula, and caveats:
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
columns:
|
|
71
|
+
- name: net_revenue
|
|
72
|
+
description: >
|
|
73
|
+
Total revenue minus refunds and discounts for the day.
|
|
74
|
+
Formula: gross_revenue - refund_amount - discount_amount.
|
|
75
|
+
Can be negative if refunds exceed sales.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 4. Validate
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
altimate-dbt compile --model <name> # ensure YAML is valid
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Common Mistakes
|
|
85
|
+
|
|
86
|
+
| Mistake | Fix |
|
|
87
|
+
|---------|-----|
|
|
88
|
+
| Restating the column name as the description | `"order_id: The order ID"` → describe business meaning |
|
|
89
|
+
| Empty descriptions | Every column should have a description. If unsure, describe the source. |
|
|
90
|
+
| Not reading the SQL before documenting | Read the model to understand derivation logic |
|
|
91
|
+
| Duplicating descriptions across models | Use doc blocks for shared definitions |
|
|
92
|
+
| Writing implementation details instead of business context | Describe what it means to the business, not how it's computed |
|
|
93
|
+
|
|
94
|
+
## Reference Guides
|
|
95
|
+
|
|
96
|
+
| Guide | Use When |
|
|
97
|
+
|-------|----------|
|
|
98
|
+
| [references/altimate-dbt-commands.md](references/altimate-dbt-commands.md) | Need the full CLI reference |
|
|
99
|
+
| [references/documentation-standards.md](references/documentation-standards.md) | Writing high-quality descriptions |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# altimate-dbt Command Reference
|
|
2
|
+
|
|
3
|
+
All dbt operations use the `altimate-dbt` CLI. Output is JSON to stdout; logs go to stderr.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
altimate-dbt <command> [args...]
|
|
7
|
+
altimate-dbt <command> [args...] --format text # Human-readable output
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## First-Time Setup
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
altimate-dbt init # Auto-detect project root
|
|
14
|
+
altimate-dbt init --project-root /path # Explicit root
|
|
15
|
+
altimate-dbt init --python-path /path # Override Python
|
|
16
|
+
altimate-dbt doctor # Verify setup
|
|
17
|
+
altimate-dbt info # Project name, adapter, root
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Build & Run
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
altimate-dbt build --model <name> [--downstream] # compile + run + test
|
|
24
|
+
altimate-dbt run --model <name> [--downstream] # materialize only
|
|
25
|
+
altimate-dbt test --model <name> # run tests only
|
|
26
|
+
altimate-dbt build-project # full project build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Compile
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
altimate-dbt compile --model <name>
|
|
33
|
+
altimate-dbt compile-query --query "SELECT * FROM {{ ref('stg_orders') }}" [--model <context>]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Execute SQL
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
altimate-dbt execute --query "SELECT count(*) FROM {{ ref('orders') }}" --limit 100
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Schema & DAG
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
altimate-dbt columns --model <name> # column names and types
|
|
46
|
+
altimate-dbt columns-source --source <src> --table <tbl> # source table columns
|
|
47
|
+
altimate-dbt column-values --model <name> --column <col> # sample values
|
|
48
|
+
altimate-dbt children --model <name> # downstream models
|
|
49
|
+
altimate-dbt parents --model <name> # upstream models
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Packages
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
altimate-dbt deps # install packages.yml
|
|
56
|
+
altimate-dbt add-packages --packages dbt-utils,dbt-expectations
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Error Handling
|
|
60
|
+
|
|
61
|
+
All errors return JSON with `error` and `fix` fields:
|
|
62
|
+
```json
|
|
63
|
+
{ "error": "dbt-core is not installed", "fix": "Install it: python3 -m pip install dbt-core" }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Run `altimate-dbt doctor` as the first diagnostic step for any failure.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Documentation Standards
|
|
2
|
+
|
|
3
|
+
## Model Descriptions
|
|
4
|
+
|
|
5
|
+
A good model description answers four questions:
|
|
6
|
+
|
|
7
|
+
1. **What**: What business entity or metric does this represent?
|
|
8
|
+
2. **Why**: Who uses it and for what purpose?
|
|
9
|
+
3. **How**: Key transformations (joins, filters, aggregations)
|
|
10
|
+
4. **Grain**: What does one row represent?
|
|
11
|
+
|
|
12
|
+
### Good Example
|
|
13
|
+
```yaml
|
|
14
|
+
description: >
|
|
15
|
+
Daily revenue by product category. One row per category per day.
|
|
16
|
+
Joins staged orders with product dimensions, calculates gross and net revenue.
|
|
17
|
+
Used by the finance team for P&L reporting and the marketing team for
|
|
18
|
+
campaign attribution.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Bad Example
|
|
22
|
+
```yaml
|
|
23
|
+
description: "This model contains daily revenue data."
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Column Descriptions
|
|
27
|
+
|
|
28
|
+
### Primary Keys
|
|
29
|
+
State that it's a primary key and where it originates:
|
|
30
|
+
```yaml
|
|
31
|
+
- name: order_id
|
|
32
|
+
description: "Primary key. Unique identifier for each order, sourced from the orders table in Stripe."
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Foreign Keys
|
|
36
|
+
State what it references:
|
|
37
|
+
```yaml
|
|
38
|
+
- name: customer_id
|
|
39
|
+
description: "Foreign key to dim_customers. The customer who placed this order."
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Calculated Columns
|
|
43
|
+
Include the formula:
|
|
44
|
+
```yaml
|
|
45
|
+
- name: net_revenue
|
|
46
|
+
description: "Gross revenue minus refunds and discounts. Formula: gross_amount - refund_amount - discount_amount. Can be negative."
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Status/Category Columns
|
|
50
|
+
List the possible values:
|
|
51
|
+
```yaml
|
|
52
|
+
- name: order_status
|
|
53
|
+
description: "Current order status. Values: pending, shipped, delivered, cancelled, refunded."
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Timestamps
|
|
57
|
+
State what event they represent:
|
|
58
|
+
```yaml
|
|
59
|
+
- name: shipped_at
|
|
60
|
+
description: "Timestamp when the order was shipped. NULL if not yet shipped. UTC timezone."
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Doc Blocks (Shared Definitions)
|
|
64
|
+
|
|
65
|
+
For definitions reused across multiple models, create doc blocks:
|
|
66
|
+
|
|
67
|
+
```markdown
|
|
68
|
+
-- docs/shared_definitions.md
|
|
69
|
+
{% docs customer_id %}
|
|
70
|
+
Unique identifier for a customer. Sourced from the customers table
|
|
71
|
+
in the CRM system. Used as the primary join key across all
|
|
72
|
+
customer-related models.
|
|
73
|
+
{% enddocs %}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Reference in YAML:
|
|
77
|
+
```yaml
|
|
78
|
+
- name: customer_id
|
|
79
|
+
description: "{{ doc('customer_id') }}"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Anti-Patterns
|
|
83
|
+
|
|
84
|
+
| Anti-Pattern | Why It's Bad | Better Approach |
|
|
85
|
+
|-------------|-------------|-----------------|
|
|
86
|
+
| `"The order ID"` | Just restates the column name | Describe origin and business meaning |
|
|
87
|
+
| `"See code"` | Defeats the purpose of docs | Summarize the logic |
|
|
88
|
+
| `""` (empty) | Missing documentation | Write something, even if brief |
|
|
89
|
+
| Technical jargon only | Business users can't understand | Lead with business meaning, add technical detail after |
|
|
90
|
+
|
|
91
|
+
## Official Documentation
|
|
92
|
+
|
|
93
|
+
- **dbt documentation**: https://docs.getdbt.com/docs/build/documentation
|
|
94
|
+
- **Doc blocks**: https://docs.getdbt.com/docs/build/documentation#using-docs-blocks
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dbt-test
|
|
3
|
+
description: Add schema tests, unit tests, and data quality checks to dbt models. Use when validating data integrity, adding test definitions to schema.yml, writing unit tests, or practicing test-driven development in dbt. Powered by altimate-dbt.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dbt Testing
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
**Agent:** builder or migrator (requires file write access)
|
|
10
|
+
**Tools used:** bash (runs `altimate-dbt` commands), read, glob, write, edit, altimate_core_testgen, altimate_core_validate
|
|
11
|
+
|
|
12
|
+
## When to Use This Skill
|
|
13
|
+
|
|
14
|
+
**Use when the user wants to:**
|
|
15
|
+
- Add tests to a model's schema.yml (unique, not_null, relationships, accepted_values)
|
|
16
|
+
- Write dbt unit tests (mock inputs → expected outputs)
|
|
17
|
+
- Create custom generic or singular tests
|
|
18
|
+
- Debug why a test is failing
|
|
19
|
+
- Practice test-driven development in dbt
|
|
20
|
+
|
|
21
|
+
**Do NOT use for:**
|
|
22
|
+
- Creating or modifying model SQL → use `dbt-develop`
|
|
23
|
+
- Writing model descriptions → use `dbt-docs`
|
|
24
|
+
- Debugging build/compilation errors → use `dbt-troubleshoot`
|
|
25
|
+
|
|
26
|
+
## The Iron Rule
|
|
27
|
+
|
|
28
|
+
**Never modify a test to make it pass without understanding why it's failing.**
|
|
29
|
+
|
|
30
|
+
A failing test is information. It means either:
|
|
31
|
+
1. The data has a real quality issue (fix the data or the model)
|
|
32
|
+
2. The test expectation is wrong (update the test with justification)
|
|
33
|
+
3. The model logic is wrong (fix the model)
|
|
34
|
+
|
|
35
|
+
Option 2 requires explicit user confirmation. Do not silently weaken tests.
|
|
36
|
+
|
|
37
|
+
## Schema Test Workflow
|
|
38
|
+
|
|
39
|
+
### 1. Discover Columns
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
altimate-dbt columns --model <name>
|
|
43
|
+
altimate-dbt column-values --model <name> --column <col>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Read Existing Tests
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
glob models/**/*schema*.yml models/**/*_models.yml
|
|
50
|
+
read <yaml_file>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 3. Generate Tests
|
|
54
|
+
|
|
55
|
+
**Auto-generate with `altimate_core_testgen`:** Pass the compiled SQL and schema to generate boundary-value, NULL-handling, and edge-case test assertions automatically. This produces executable test SQL covering cases you might miss manually.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
altimate_core_testgen(sql: <compiled_sql>, schema_context: <schema_object>)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Review the generated tests — keep what makes sense, discard trivial ones. Then apply test rules based on column patterns — see [references/schema-test-patterns.md](references/schema-test-patterns.md).
|
|
62
|
+
|
|
63
|
+
### 4. Write YAML
|
|
64
|
+
|
|
65
|
+
Merge into existing schema.yml (don't duplicate). Use `edit` for existing files, `write` for new ones.
|
|
66
|
+
|
|
67
|
+
### 5. Validate SQL
|
|
68
|
+
|
|
69
|
+
Before running, validate the compiled model SQL to catch syntax and schema errors early:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
altimate_core_validate(sql: <compiled_sql>, schema_context: <schema_object>)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 6. Run Tests
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
altimate-dbt test --model <name> # run tests for this model
|
|
79
|
+
altimate-dbt build --model <name> # build + test together
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Unit Test Workflow
|
|
83
|
+
|
|
84
|
+
See [references/unit-test-guide.md](references/unit-test-guide.md) for the full unit test framework.
|
|
85
|
+
|
|
86
|
+
### Quick Pattern
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
unit_tests:
|
|
90
|
+
- name: test_order_total_calculation
|
|
91
|
+
model: fct_orders
|
|
92
|
+
given:
|
|
93
|
+
- input: ref('stg_orders')
|
|
94
|
+
rows:
|
|
95
|
+
- { order_id: 1, quantity: 3, unit_price: 10.00 }
|
|
96
|
+
- { order_id: 2, quantity: 1, unit_price: 25.00 }
|
|
97
|
+
expect:
|
|
98
|
+
rows:
|
|
99
|
+
- { order_id: 1, order_total: 30.00 }
|
|
100
|
+
- { order_id: 2, order_total: 25.00 }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Common Mistakes
|
|
104
|
+
|
|
105
|
+
| Mistake | Fix |
|
|
106
|
+
|---------|-----|
|
|
107
|
+
| Testing every column with `not_null` | Only test columns that should never be null. Think about what NULL means. |
|
|
108
|
+
| Missing `unique` test on primary keys | Every primary key needs `unique` + `not_null` |
|
|
109
|
+
| `accepted_values` with incomplete list | Use `altimate-dbt column-values` to discover real values first |
|
|
110
|
+
| Modifying a test to make it pass | Understand WHY it fails first. The test might be right. |
|
|
111
|
+
| No `relationships` test on foreign keys | Add `relationships: {to: ref('parent'), field: parent_id}` |
|
|
112
|
+
| Unit testing trivial logic | Don't unit test `SELECT a, b FROM source`. Test calculations and business logic. |
|
|
113
|
+
|
|
114
|
+
## Reference Guides
|
|
115
|
+
|
|
116
|
+
| Guide | Use When |
|
|
117
|
+
|-------|----------|
|
|
118
|
+
| [references/altimate-dbt-commands.md](references/altimate-dbt-commands.md) | Need the full CLI reference |
|
|
119
|
+
| [references/schema-test-patterns.md](references/schema-test-patterns.md) | Adding schema.yml tests by column pattern |
|
|
120
|
+
| [references/unit-test-guide.md](references/unit-test-guide.md) | Writing dbt unit tests |
|
|
121
|
+
| [references/custom-tests.md](references/custom-tests.md) | Creating generic or singular tests |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# altimate-dbt Command Reference
|
|
2
|
+
|
|
3
|
+
All dbt operations use the `altimate-dbt` CLI. Output is JSON to stdout; logs go to stderr.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
altimate-dbt <command> [args...]
|
|
7
|
+
altimate-dbt <command> [args...] --format text # Human-readable output
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## First-Time Setup
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
altimate-dbt init # Auto-detect project root
|
|
14
|
+
altimate-dbt init --project-root /path # Explicit root
|
|
15
|
+
altimate-dbt init --python-path /path # Override Python
|
|
16
|
+
altimate-dbt doctor # Verify setup
|
|
17
|
+
altimate-dbt info # Project name, adapter, root
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Build & Run
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
altimate-dbt build --model <name> [--downstream] # compile + run + test
|
|
24
|
+
altimate-dbt run --model <name> [--downstream] # materialize only
|
|
25
|
+
altimate-dbt test --model <name> # run tests only
|
|
26
|
+
altimate-dbt build-project # full project build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Compile
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
altimate-dbt compile --model <name>
|
|
33
|
+
altimate-dbt compile-query --query "SELECT * FROM {{ ref('stg_orders') }}" [--model <context>]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Execute SQL
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
altimate-dbt execute --query "SELECT count(*) FROM {{ ref('orders') }}" --limit 100
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Schema & DAG
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
altimate-dbt columns --model <name> # column names and types
|
|
46
|
+
altimate-dbt columns-source --source <src> --table <tbl> # source table columns
|
|
47
|
+
altimate-dbt column-values --model <name> --column <col> # sample values
|
|
48
|
+
altimate-dbt children --model <name> # downstream models
|
|
49
|
+
altimate-dbt parents --model <name> # upstream models
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Packages
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
altimate-dbt deps # install packages.yml
|
|
56
|
+
altimate-dbt add-packages --packages dbt-utils,dbt-expectations
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Error Handling
|
|
60
|
+
|
|
61
|
+
All errors return JSON with `error` and `fix` fields:
|
|
62
|
+
```json
|
|
63
|
+
{ "error": "dbt-core is not installed", "fix": "Install it: python3 -m pip install dbt-core" }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Run `altimate-dbt doctor` as the first diagnostic step for any failure.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Custom dbt Tests
|
|
2
|
+
|
|
3
|
+
## Generic Tests (Reusable)
|
|
4
|
+
|
|
5
|
+
Generic tests are macros in `tests/generic/` or `macros/` that accept parameters:
|
|
6
|
+
|
|
7
|
+
```sql
|
|
8
|
+
-- tests/generic/test_positive_values.sql
|
|
9
|
+
{% test positive_values(model, column_name) %}
|
|
10
|
+
|
|
11
|
+
select *
|
|
12
|
+
from {{ model }}
|
|
13
|
+
where {{ column_name }} < 0
|
|
14
|
+
|
|
15
|
+
{% endtest %}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Usage in schema.yml:
|
|
19
|
+
```yaml
|
|
20
|
+
columns:
|
|
21
|
+
- name: amount
|
|
22
|
+
tests:
|
|
23
|
+
- positive_values
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Singular Tests (One-Off)
|
|
27
|
+
|
|
28
|
+
Singular tests are standalone SQL files in `tests/` that return failing rows:
|
|
29
|
+
|
|
30
|
+
```sql
|
|
31
|
+
-- tests/assert_no_orphan_orders.sql
|
|
32
|
+
-- Orders must have a matching customer
|
|
33
|
+
select o.order_id
|
|
34
|
+
from {{ ref('fct_orders') }} o
|
|
35
|
+
left join {{ ref('dim_customers') }} c on o.customer_id = c.customer_id
|
|
36
|
+
where c.customer_id is null
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
A passing test returns zero rows.
|
|
40
|
+
|
|
41
|
+
## When to Use Which
|
|
42
|
+
|
|
43
|
+
| Type | Use When |
|
|
44
|
+
|------|----------|
|
|
45
|
+
| Schema tests (built-in) | `unique`, `not_null`, `accepted_values`, `relationships` |
|
|
46
|
+
| dbt-utils tests | `expression_is_true`, `unique_combination_of_columns` |
|
|
47
|
+
| Generic tests (custom) | Reusable validation logic across multiple models |
|
|
48
|
+
| Singular tests | One-off business rules, cross-model assertions |
|
|
49
|
+
| Unit tests | Testing calculation logic with mocked inputs |
|
|
50
|
+
|
|
51
|
+
## Naming Conventions
|
|
52
|
+
|
|
53
|
+
- Generic tests: `test_<what_it_checks>.sql` in `tests/generic/`
|
|
54
|
+
- Singular tests: `assert_<business_rule>.sql` in `tests/`
|
|
55
|
+
|
|
56
|
+
## Official Documentation
|
|
57
|
+
|
|
58
|
+
- **Data tests**: https://docs.getdbt.com/docs/build/data-tests
|
|
59
|
+
- **Custom generic tests**: https://docs.getdbt.com/docs/build/data-tests#generic-data-tests
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Schema Test Patterns
|
|
2
|
+
|
|
3
|
+
## Test Generation Rules
|
|
4
|
+
|
|
5
|
+
Apply tests based on column name patterns:
|
|
6
|
+
|
|
7
|
+
| Column Pattern | Tests |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `*_id` (primary key) | `unique`, `not_null` |
|
|
10
|
+
| `*_id` (foreign key) | `not_null`, `relationships: {to: ref('parent'), field: id}` |
|
|
11
|
+
| `status`, `type`, `category` | `accepted_values` (discover values with `altimate-dbt column-values`) |
|
|
12
|
+
| `*_at`, `*_date`, `*_timestamp` | `not_null` (if event timestamp that should always exist) |
|
|
13
|
+
| `is_*`, `has_*` (booleans) | `accepted_values: [true, false]` |
|
|
14
|
+
| Columns in JOIN conditions | `not_null` (nulls cause dropped rows in INNER JOIN) |
|
|
15
|
+
|
|
16
|
+
## Test Priority Framework
|
|
17
|
+
|
|
18
|
+
Not every column needs every test. Prioritize:
|
|
19
|
+
|
|
20
|
+
### Tier 1: Always Test (Primary Keys)
|
|
21
|
+
```yaml
|
|
22
|
+
- name: order_id
|
|
23
|
+
tests:
|
|
24
|
+
- unique
|
|
25
|
+
- not_null
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Tier 2: Test Foreign Keys
|
|
29
|
+
```yaml
|
|
30
|
+
- name: customer_id
|
|
31
|
+
tests:
|
|
32
|
+
- not_null
|
|
33
|
+
- relationships:
|
|
34
|
+
to: ref('dim_customers')
|
|
35
|
+
field: customer_id
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Tier 3: Test Business-Critical Columns
|
|
39
|
+
```yaml
|
|
40
|
+
- name: order_status
|
|
41
|
+
tests:
|
|
42
|
+
- not_null
|
|
43
|
+
- accepted_values:
|
|
44
|
+
values: ['pending', 'shipped', 'delivered', 'cancelled']
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Tier 4: Test Derived Columns (When Logic is Complex)
|
|
48
|
+
```yaml
|
|
49
|
+
- name: net_revenue
|
|
50
|
+
tests:
|
|
51
|
+
- not_null
|
|
52
|
+
- dbt_utils.expression_is_true:
|
|
53
|
+
expression: ">= 0"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Discovering Values for accepted_values
|
|
57
|
+
|
|
58
|
+
Before adding `accepted_values`, discover what actually exists:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
altimate-dbt column-values --model <name> --column status
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This prevents false test failures from values you didn't know about.
|
|
65
|
+
|
|
66
|
+
## Cost-Conscious Testing
|
|
67
|
+
|
|
68
|
+
For large tables, add `where` clauses to expensive tests:
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
- name: order_id
|
|
72
|
+
tests:
|
|
73
|
+
- unique:
|
|
74
|
+
config:
|
|
75
|
+
where: "order_date >= current_date - interval '30 days'"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## dbt-utils Test Extensions
|
|
79
|
+
|
|
80
|
+
Common additional tests from `dbt-utils`:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
# Ensure expression evaluates to true for all rows
|
|
84
|
+
- dbt_utils.expression_is_true:
|
|
85
|
+
expression: "amount >= 0"
|
|
86
|
+
|
|
87
|
+
# Ensure no duplicate combinations
|
|
88
|
+
- dbt_utils.unique_combination_of_columns:
|
|
89
|
+
combination_of_columns:
|
|
90
|
+
- date_day
|
|
91
|
+
- customer_id
|
|
92
|
+
|
|
93
|
+
# Ensure referential integrity across multiple columns
|
|
94
|
+
- dbt_utils.relationships_where:
|
|
95
|
+
to: ref('dim_products')
|
|
96
|
+
field: product_id
|
|
97
|
+
from_condition: "product_id is not null"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Official Documentation
|
|
101
|
+
|
|
102
|
+
- **dbt tests**: https://docs.getdbt.com/docs/build/data-tests
|
|
103
|
+
- **dbt-utils tests**: https://github.com/dbt-labs/dbt-utils#generic-tests
|