generate
Generate relational synthetic SQL from a hand-authored YAML model, a model inferred from a SQL dump, or an inferred model plus explicit overrides.
Alias: gen (e.g., sql-splitter gen production.sql -o synthetic.sql)
When to Use This
Section titled “When to Use This”- Seed relational fixtures — Produce data that satisfies its own primary keys and foreign keys, so it loads cleanly into the same schema
- Share safe datasets — Ship synthetic dumps that keep a real schema’s shape without exposing its rows
- Make CI fixtures repeatable — Pin
--seedso every run produces byte-identical output - Scale a dataset up or down — Multiply or cap row counts with
--scale,--rows, and per-table overrides for load tests or small demos - Derive a model from a real dump — Profile and infer a starting model automatically, then edit and reuse it
Use redact instead when you must anonymize the real rows rather than synthesize new ones.
How It Works
Section titled “How It Works”generate turns a model into SQL. When you pass a source dump, it derives that model first, without ever loading the full dataset into memory:
- Profile — A bounded
basic/fullstreaming profiler samples the dump’s columns within a fixed memory budget - Infer — Structural referential-integrity and column heuristics resolve an explicit per-column rule for each table
- Compile — The model is validated and resolved into a plan (row counts, dependency order, key domains)
- Render — The engine produces
CREATE TABLEDDL and batchedINSERT/COPYrows in the target dialect
A hand-authored --config model skips the profile and infer steps. See
Profiling and inference for how rules are chosen and
Privacy and verification for what --verify audits.
sql-splitter generate [OPTIONS] [INPUT]Provide a source dump, a complete --config model, or both. A kind: overrides
document requires a source dump or base model because it patches the inferred model
rather than standing alone.
Examples
Section titled “Examples”Generate from a dump
Section titled “Generate from a dump”# Profile production.sql, infer a model, and generate synthetic SQLsql-splitter generate production.sql -o synthetic.sqlRepeatable fixtures from a model
Section titled “Repeatable fixtures from a model”# A pinned seed makes the output byte-identical across runssql-splitter generate --config model.yaml --seed 42 -o synthetic.sqlInfer and save an editable model
Section titled “Infer and save an editable model”# Write the resolved model without generating SQL, then edit and reuse itsql-splitter generate production.sql --emit-config model.yamlsql-splitter generate --config model.yaml -o synthetic.sqlApply overrides and scale in one run
Section titled “Apply overrides and scale in one run”# Patch the inferred model, save the resolved model, and emit 10% of the rowssql-splitter generate production.sql \ --config overrides.yaml \ --emit-config resolved.yaml \ --scale 0.1 \ -o synthetic.sqlPreflight (check, dry-run, verify)
Section titled “Preflight (check, dry-run, verify)”# Parse and compile a complete model; write nothingsql-splitter generate --config model.yaml --check
# Resolve counts and dependencies without generating rowssql-splitter generate --config model.yaml --dry-run
# Explain inferred column rules without printing observed valuessql-splitter generate production.sql --dry-run --explain
# Generate, audit exact constraints, then publish atomicallysql-splitter generate --config model.yaml --verify -o synthetic.sql--strict promotes warning-severity diagnostics to failures; informational
diagnostics and advisories stay non-fatal. --quiet suppresses the ordinary human
report, but safety advisories still reach stderr.
Options
Section titled “Options”Input and model
Section titled “Input and model”| Flag | Short | Description | Default |
|---|---|---|---|
[INPUT] | Source SQL dump to profile | none | |
--config | -c | Complete model or overrides YAML | none |
--emit-config | Write the resolved complete model | none | |
--output | -o | Generated SQL; - means stdout | stdout |
--profile-depth | Profiling depth: basic or full | basic | |
--profile-sample | Retained profiling sample capacity | 1000 | |
--input-dialect | Force the source parsing dialect | auto-detect |
Rendering
Section titled “Rendering”| Flag | Short | Description | Default |
|---|---|---|---|
--dialect | Output SQL dialect | model, source, then MySQL | |
--schema-only | Emit DDL only | false | |
--data-only | Emit row data only | false | |
--batch-size | Rows per INSERT/COPY batch (1–1,000,000) | 1000 | |
--no-copy | Use PostgreSQL INSERT instead of COPY | false | |
--mssql-production-style | Add production-style MSSQL DDL conventions | false | |
--mssql-go | Emit GO every N MSSQL insert batches | every batch | |
--compress | Reserved; currently unavailable | none |
Volume and selection
Section titled “Volume and selection”| Flag | Short | Description | Default |
|---|---|---|---|
--scale | Multiply every resolved row count | none | |
--rows | Set absolute root-table counts | none | |
--table-rows | Per-table absolute count (table=count); repeatable | none | |
--table-scale | Per-table scale (table=factor); repeatable | none | |
--max-rows | Cap every table, including family-planner children, last | none | |
--tables | Include matching tables and required dependencies | all | |
--exclude | Exclude matching tables | none |
Randomness
Section titled “Randomness”| Flag | Short | Description | Default |
|---|---|---|---|
--seed | Stable root seed | model or fresh entropy | |
--randomize | Ignore the configured seed; use a new one | false |
Preflight and reporting
Section titled “Preflight and reporting”| Flag | Short | Description | Default |
|---|---|---|---|
--check | Compile a complete model only | false | |
--dry-run | Compile and report resolved counts | false | |
--verify | Generate, audit, and publish atomically | false | |
--explain | Include inference decisions | false | |
--strict | Fail on warning-severity diagnostics | false | |
--json | Print a machine-readable report on stdout | false | |
--quiet | Suppress ordinary human reporting | false | |
--progress | Accepted but not wired to generation | false |
Constraints
Section titled “Constraints”--check,--dry-run, and--verifyare mutually exclusive.--schema-onlyand--data-onlyare mutually exclusive.--seedand--randomizeare mutually exclusive.--scaleand--rowsare mutually exclusive.- A table cannot receive both
--table-rowsand--table-scale. --json,--output -, and--emit-config -each own stdout; select only one.--jsonwrites only the report to stdout, so it needs-o <path>for the generated SQL (or a report-only--check/--dry-runrun).--checkrequires a complete model and cannot profile[INPUT].--verifyrequires a real output path and cannot use compression.- MSSQL-specific flags require an explicit
--dialect mssql.
JSON Output
Section titled “JSON Output”--json writes a machine-readable report to stdout, so pair it with -o <path> for
the generated SQL (or use --check/--dry-run for a report-only run):
sql-splitter generate --config model.yaml --seed 42 -o synthetic.sql --json{ "mode": "generate", "rows_written": 65, "effective_seed": 42, "diagnostics": [ { "code": "GEN-SOURCE-VALUES", "severity": "advisory", "path": "tables", "message": "2 rule(s) replay hand-authored literal values; the output is synthetic, not anonymized source data", "documentation_url": "https://sql-splitter.dev/commands/generate/diagnostics/#GEN-SOURCE-VALUES", "related": [ { "path": "tables.customers.columns.notes", "description": "constant" }, { "path": "tables.orders.columns.status", "description": "source_default" } ] } ]}mode is generate, dry_run, or check. Every diagnostic carries a stable
code, a severity, the config path it applies to, and a documentation_url.
Exit Codes
Section titled “Exit Codes”| Code | Meaning |
|---|---|
0 | Generation or the requested preflight mode succeeded |
1 | Model, warning-under-strict, runtime, I/O, or verification failure |
2 | Invalid CLI usage or conflicting flags |
See Exit Codes for scripting examples.
Composing with Other Tools
Section titled “Composing with Other Tools”Infer → edit → reuse
Section titled “Infer → edit → reuse”# Save the inferred model, hand-tune it, then generate from the frozen modelsql-splitter generate production.sql --emit-config model.yaml$EDITOR model.yamlsql-splitter generate --config model.yaml --seed 42 -o synthetic.sqlGenerate → validate
Section titled “Generate → validate”# Confirm the synthetic dump parses and its foreign keys resolvesql-splitter generate --config model.yaml -o synthetic.sqlsql-splitter validate synthetic.sql(--verify runs an equivalent audit inline and only publishes on success.)
Generate → split
Section titled “Generate → split”# Generate one dump, then break it into per-table filessql-splitter generate --config model.yaml -o synthetic.sqlsql-splitter split synthetic.sql -o tables/Sample → generate
Section titled “Sample → generate”# Reduce a huge production dump first, then synthesize from the smaller samplesql-splitter sample production.sql --rows 5000 -o sample.sqlsql-splitter generate sample.sql -o synthetic.sqlTroubleshooting
Section titled “Troubleshooting”Conflicting flags rejected with exit code 2
Section titled “Conflicting flags rejected with exit code 2”Symptom: The command exits immediately with a message about mutually exclusive options.
Cause: Two flags that own the same behavior were passed together — for example --check with --verify, --scale with --rows, or --seed with --randomize.
Fix: Keep one flag from each conflicting pair. See Constraints for the full list.
--json prints a report but no SQL appears
Section titled “--json prints a report but no SQL appears”Symptom: With --json you get the report on stdout, but no generated SQL.
Cause: In generate mode --json owns stdout and emits only the report, so the SQL has nowhere to go.
Fix: Add -o <path> for the SQL, or use --check/--dry-run for a report-only run.
--check fails asking for a complete model
Section titled “--check fails asking for a complete model”Symptom: --check errors when you pass a source dump.
Cause: --check validates a complete --config model and does not profile [INPUT].
Fix: Run --check against a --config model, or use --dry-run to compile and report counts for a profiled dump.
MSSQL flags are rejected
Section titled “MSSQL flags are rejected”Symptom: --mssql-production-style or --mssql-go errors.
Cause: These flags only apply to MSSQL output and require the dialect to be set explicitly.
Fix: Add --dialect mssql.
Output looks like real data
Section titled “Output looks like real data”Symptom: Generated values match values from the source dump, and a GEN-SOURCE-VALUES advisory appears.
Cause: Some rules (constants, replayed defaults, observed samples) can reproduce literal values. The output is synthetic, not anonymized.
Fix: Review the rules the advisory names, or replace them with non-replaying generators. To anonymize real rows instead, use redact.
See Also
Section titled “See Also”Generate’s detail lives in dedicated reference pages:
- Model reference — the YAML model language
- Generators — per-column value producers
- Modifiers — post-generation value transforms
- Planners — coordinated multi-column and parent/child invariants
- Profiling and inference — how a model is derived from a dump
- Privacy and verification — safety advisories and exact checks
- Diagnostics — stable
GEN-*codes and anchors - Rust API — embedding generation in Rust
Related commands and references:
redact— Anonymize real data instead of synthesizing new datasample— Reduce a real dump before profiling itvalidate— Check the generated dump’s integrity- Dialects — Dialect-specific output behavior
- JSON Output Schema — Schema for
--jsonoutput