Skip to content
Back to skills

308 Discovering Data C9eedadd

ASecurity

Use `dbt show` to interactively explore raw data, understand table structures, and document findings for downstream model development.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
researchgobashsqlnodetestingdocumentation

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 308-discovering-data_c9eedadd --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 308 Discovering Data C9eedadd?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 308 Discovering Data C9eedadd
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-308-discovering-data-c9eedadd/badge)](https://www.skillsdirectory.com/skills/tools-only-308-discovering-data-c9eedadd)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Discovering Data with dbt show

Use `dbt show` to interactively explore raw data, understand table structures, and document findings for downstream model development.

## When to Use

- Onboarding to a new dbt project with unfamiliar source data
- Investigating data quality issues reported by stakeholders
- Planning new models and need to understand source grain/structure
- Mapping relationships between tables before building joins

## The Iron Rule

**Complete all 6 steps for every table you will build models on.**

## Rationalizations That Mean STOP

| You're Thinking... | Reality |
|-------------------|---------|
| "I don't have time for full discovery" | You don't have time for wrong models. |
| "It's just a quick stakeholder briefing" | Quick briefings become "can you build a model from this?" You need to do full discovery before building anything. |
| "I'll do proper discovery later" | You won't. Document now or create technical debt someone else inherits. |
| "This is technical debt I'm accepting" | You're not accepting it - you're passing it to your future self or teammates. |
| "47 tables is too many for full methodology" | Then prioritize which tables you'll actually use and do full discovery on those. Don't half-discover everything. |
| "I'll just do the critical tables thoroughly" | ALL tables you build on are critical. If it's not worth full discovery, don't build models on it yet. |
| "Standard patterns, I know this data" | You know the pattern. This instance's data might vary. Verify. |

## Red Flags - You're About to Skip Steps

Stop if you catch yourself:
- Running only `SELECT *` without grain analysis
- Saying "the join worked" without checking orphan counts
- Noting "some nulls" without quantifying null rates
- Planning to "document later"
- Feeling time pressure and reaching for shortcuts
- Treating a large table count as permission to be less thorough

**All of these mean: slow down, follow all 6 steps.**

## Large Scope Strategy

When facing many tables (20+), the answer is NOT abbreviated discovery. The answer is:

1. **Scope ruthlessly first** - Which tables will you actually build models on? Only those need discovery now.
2. **Full methodology on scoped tables** - Every table in scope gets all 6 steps. No exceptions.
3. **Explicit deferral for out-of-scope** - Document which tables you're NOT discovering and why. "Not needed for current project" is valid. "Too many tables" is not.

**Wrong approach:** "I'll do light discovery on all 47 tables"
**Right approach:** "I'll do full discovery on the 8 tables needed for this project"

## Core Method: Iterative Discovery

### Step 1: Inventory relevant objects

#### Sources

When discovering new raw data, list all tables from the new source. E.g. listing all `ecom` source tables:

```bash
# quoting is critical when selecting sources
dbt ls --select "source:ecom.*" --output json
```

Review the existing YAML file at `original_file_path` to understand what's already documented.

#### Models

When previewing existing models, use standard node selection syntax:

```bash
# quoting is critical when selecting multiple nodes
dbt ls --select "my_first_model my_second_model" --output json
```

Review existing YAML files (normally colocated with the model's `original_file_path`) to understand what's already documented.

### Step 2: Sample Raw Data

Preview rows from each source table:

```bash
dbt show --inline "SELECT * FROM {{ source('source_name', 'table_name') }}" --limit 50 --output json
```

**Document immediately:**

- Column names and warehouse-native data types
- Which columns appear to be identifiers vs attributes
- Obvious nulls, low-cardinality values, and values which are not obvious from their column name

### Run standard EDA

Continue to use `dbt show` to run standard exploratory data analysis queries such as:

- Identify the grain of the table
- Check for duplicate/null primary keys
- Validate data ranges make sense (e.g. event timestamps are in the past)
- Profile key columns
- Identify potential foreign key relationships
- Inconsistent data types in a column

## Documenting Findings

Create a discovery report that other agents can consume. Place in a `data_discovery.md` file alongside the SQL/YAML files. Do not use Jinja in these discovery files to avoid them being mistaken for doc blocks.

### Discovery Report Template

```markdown
## Source: {source_name}.{table_name}

### Overview
- **Row count**: X
- **Grain**: One row per [entity] per [time period]
- **Primary key**: column_name (verified unique)

### Column Analysis
| Column | Type | Nulls | Notes |
|--------|------|-------|-------|
| id | integer | 0% | Primary key |
| status | string | 2% | Values: active, inactive, pending |
| created_at | timestamp | 0% | UTC timezone |

### Data Quality Issues
- [ ] `status` has 15 rows with value "unknown" - clarify with stakeholder
- [ ] `amount` has negative values - confirm if valid or error

### Relationships
- `user_id` → `users.id` (5 orphan records found)
- `product_id` → `products.id` (clean join)

### Recommended Staging Transformations
1. Filter out `status = 'unknown'` rows or map to valid value
2. Cast `created_at` to consistent timezone
3. Add surrogate key if natural key unreliable
```

## Previewing Data Efficiently

When using `dbt show --inline` to preview data, push `LIMIT` clauses as early as possible in CTEs to minimize data scanning. Never add a `LIMIT` at the end of the query - `dbt show` always adds an additional limit and you will cause a syntax error.

```sql
-- ✅ GOOD: Limit pushed early, minimizes scanning
with orders as (
    select * from {{ source('ecom', 'orders') }} limit 100
),
customers as (
    select * from {{ source('ecom', 'customers') }} limit 100
)
select ... from orders join customers ...

-- ❌ BAD: Full table scan before limit applied
with orders as (
    select * from {{ source('ecom', 'orders') }}
),
customers as (
    select * from {{ source('ecom', 'customers') }}
)
select ... from orders join customers ...
limit 100  -- Too late, and redundant with --limit flag
```

## Common Mistakes

**Assuming column names reflect content**. Always verify with sample data; `customer_id` might contain account IDs

**Not documenting findings**. Discovery without documentation wastes effort; write it down immediately

**Testing relationships on sampled data only**. Orphan records may exist outside your sample; run full counts

**Ignoring soft deletes**. Check for `deleted_at`, `is_active`, or `status` columns that filter valid records

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.