CLI Filters
Run one tenant, one region, or one connector instead of the whole pipeline. Pass --filter key=value and the command works on only the sources that match.
Commands that accept --filter
Section titled “Commands that accept --filter”--filter is optional everywhere. Omit it and the command processes every source the pipeline discovers.
| Command | What gets filtered |
|---|---|
rocky plan |
Which sources get SQL statements generated. rocky apply <plan-id> then materializes only those sources end to end: drift, create, copy, check. |
rocky run |
Which sources get materialized in the single-step discover → drift → create → copy → check path. |
rocky compare |
Which shadow-versus-production tables get compared. |
rocky discover takes no filter. It always reports every source the pipeline’s adapter returns, because filtering belongs to the consumer: discover builds the catalog, the other commands narrow it.
rocky discover ──► lists every source. It hands nothing to another command.
rocky plan ┐ rocky run ├──► discovers ──► applies ──► acts on the rocky compare ┘ every source --filter matching sourcesSyntax
Section titled “Syntax”--filter <key>=<value>Pass exactly one key=value pair per invocation. The first = separates the key from the value. Any further = belongs to the value, so a value may itself contain one:
# Value "a=b" — the first = is the separatorrocky plan --filter name=a=bid — the reserved key
Section titled “id — the reserved key”Matches the connector’s unique identifier, as the source adapter reports it. For Fivetran that is the connector id, such as conn_abc123. For another adapter it is whatever that adapter’s SDK calls the primary key.
id skips schema parsing entirely, so the source does not even need a parseable schema name to match. Use it to pin a run to one connector whatever its naming convention.
rocky plan --filter id=conn_abc123Any other key — parsed schema component
Section titled “Any other key — parsed schema component”Every other key names a component that the pipeline’s schema_pattern parsed out of the source schema name. A schema like src__acme__us_west__shopify is not one opaque string to Rocky: the pattern splits it into named parts, and those part names are your filter keys. The key must match a component declared in rocky.toml:
[pipeline.bronze.source.schema_pattern]prefix = "src__"separator = "__"components = ["tenant", "regions...", "source"]With that pattern, the valid keys are tenant, regions, source, the reserved id, and the reserved table below. An unknown key — --filter department=finance against this pattern — matches nothing. Rocky raises no error and the command proceeds with zero sources in scope.
table — the second reserved key
Section titled “table — the second reserved key”table filters within a matched source rather than between sources. Every source passes at the connector level, and Rocky then narrows each one’s discovered table list to tables whose name equals the value exactly:
# Copy only the `orders` table from every in-scope sourcerocky plan --filter table=ordersMatching is exact and literal. There are no globs: --filter table=orders_* looks for a table actually named orders_*, which almost never exists. Glob-style table selection lives in the TOML [[table_overrides]] grammar instead.
Matching semantics
Section titled “Matching semantics”Single-valued components
Section titled “Single-valued components”A plain variable like tenant matches by equality:
# Matches sources whose parsed tenant == "acme"rocky plan --filter tenant=acmeMulti-valued components (...)
Section titled “Multi-valued components (...)”A component declared with the ... suffix, such as regions... above, holds several parsed values at once. A filter matches it by containment, not equality:
# Matches every source whose parsed regions list CONTAINS "us_west"# — so src__acme__us_west__shopify matches, and so does# src__acme__us_west__us_central__shopify, and so does# src__globex__emea__france__us_west__stripe.rocky plan --filter regions=us_westIn a multi-region pipeline this is almost always what you want: “run everything that touches us-west”.
Case sensitivity
Section titled “Case sensitivity”Rocky matches keys and values exactly as written, case included. tenant=acme does not match a source parsed as tenant=ACME. Match your upstream’s casing.
Common patterns
Section titled “Common patterns”Run a single tenant’s entire pipeline
Section titled “Run a single tenant’s entire pipeline”rocky plan --filter tenant=acmeDry-run a single connector by id
Section titled “Dry-run a single connector by id”rocky plan --filter id=conn_abc123Compare every source in one region across multi-region tenants
Section titled “Compare every source in one region across multi-region tenants”rocky compare --filter regions=us_westRun one connector type across every tenant
Section titled “Run one connector type across every tenant”rocky plan --filter source=stripeScope by a custom component
Section titled “Scope by a custom component”If your pattern is ["environment", "department", "system"], any of those become valid filter keys:
rocky plan --filter department=financerocky plan --filter system=sapGrammar
Section titled “Grammar”filter = key "=" valuekey = "id" | "table" | <component name from schema_pattern>value = any non-empty stringThe flag stays optional on plan, run, and compare. When you do pass one, a typo in the key or the value — --filter tenat=acme — matches nothing. The command scopes to zero sources and exits successfully. Rocky never widens a failed match back to “everything”.
What’s NOT supported today
Section titled “What’s NOT supported today”People ask for these often. None of them work yet:
- Boolean combinations. One filter per invocation.
--filter 'tenant=acme AND regions=us_west'is not a thing. Workaround: tighten your schema pattern so a single component is the narrowing axis, or run multiple invocations. - Negation / exclusion.
--filter tenant!=acmeis not a thing. Workaround: run per-tenant filters. - Wildcards or regex.
--filter tenant=acme*is not a thing. Workaround: use a more specific pattern or run multiple invocations. - Multiple
--filterflags. clap rejects a repeated--filterat parse time (error: the argument '--filter <FILTER>' cannot be used multiple times). One filter per invocation. - Partial match / substring. Value matching is strict equality (or containment for multi-valued components, exact-literal for
table). - Glob / wildcard table names. The
table=key matches an exact table name only; glob-style selection lives in the TOML[[table_overrides]]grammar, not on the CLI.
If any of these bite you, open an issue; several of them are on the roadmap.
Error messages
Section titled “Error messages”Rocky names the problem when a filter will not parse:
| Input | Error |
|---|---|
rocky plan --filter noequalssign |
invalid filter 'noequalssign': expected key=value (e.g., client=acme) |
rocky plan --filter a=1 --filter b=2 |
clap: error: the argument '--filter <FILTER>' cannot be used multiple times |
A filter that parses but matches zero sources is not an error. The command scopes to zero sources and exits successfully. That is deliberate: an empty match is a valid orchestration result, as in “no tenant had new data this tick”.
Related
Section titled “Related”- Schema Patterns — how Rocky parses a source schema name into the components you filter on
- CLI Reference — every command and flag
- Core pipeline commands —
plan,apply, andcomparein detail - Glossary — plain definitions of the terms on this page