Schema-adaptive test data generator: point it at a database, get realistic relational test data back
Project description
Test Data Workbench
Point it at a database. Get realistic, relationally intact test data back.
Test Data Workbench reflects an unknown schema, classifies what each table represents, and emits working Python generators for it: dependency-ordered, referentially consistent, and readable. The output is not a black box; it is plain generator code you can read, edit, and commit.
Documentation: https://volanticsystems.github.io/test-data-workbench/
Quickstart
pipx install git+https://github.com/VolanticSystems/test-data-workbench.git
# Zero-setup demo: builds a small SQLite shop database and runs the full flow
tdw demo --seed 42
# Or against your own database
tdw analyze "sqlite:///shop.db"
tdw deploy "sqlite:///shop.db" --output ./generated --seed 42
# Read structure only, never touch row data
tdw analyze "postgresql://user:pass@host/db" --metadata-only
tdw deploy produces a complete working set in well under a second for typical schemas:
generated/
├── generators/ # One runnable Python generator per table
├── scenarios/ # Volume presets (small_store, growing_business, enterprise, testing)
├── config.yaml # Regeneration config
└── CONTRIBUTING.md # How to extend the generated code
Design
Three decisions shape the system:
Generated code is the product. Instead of generating rows behind an API, the Workbench generates generator source code from your schema. You can diff it, extend it, and check it into your repo. When the tool is wrong about a column, you fix one obvious line, not a configuration DSL.
Degrade, never fail. Every generation path has a four-level fallback ladder (specialized → generic → simple → minimal). An unrecognized table gets a plainer generator, not a stack trace. Failures are isolated per table and reported, not cascaded.
Determinism on demand. --seed makes any run exactly reproducible: same seed, same schema, byte-identical artifacts and identical generated records. CI fixtures stay stable across machines and runs.
The reasoning behind each is written up in the documentation.
Architecture
graph TB
subgraph "Interface"
CLI[tdw CLI]
API[FastAPI REST API]
end
subgraph "Adaptation Engine"
SA[Schema Analyzer]
GF[Generator Factory]
CB[Config Builder]
RD[Rapid Deployment]
end
subgraph "Safety"
DM[Defensive Manager]
TG[Template Generator]
V[Validators]
end
CLI --> SA
CLI --> RD
API --> RD
SA --> GF
GF --> CB
RD --> SA
DM --> GF
TG --> CB
V --> DM
- Schema Analyzer reflects tables, columns, keys, and foreign-key relationships via SQLAlchemy, then classifies each table's entity type with scored name heuristics.
- Generator Factory turns the analysis into per-table generator classes, topologically sorted so parents generate before children (with cycle detection; a cyclic schema degrades gracefully instead of hanging).
- Defensive Manager owns the fallback ladder and per-generator error isolation.
- Validators gate generated and contributed code: AST-level syntax checks, import safety, required-method presence.
After generation, a constraint check verifies the output satisfies primary-key uniqueness, not-null, and foreign-key integrity, and reports the result.
Data access and privacy
Analysis is metadata-first: structure comes from schema reflection, not your rows. By default the analyzer samples a bounded number of rows per table (LIMIT 100) to detect value patterns.
Pass --metadata-only and the analyzer issues zero SQL statements that read table data: no SELECT, no COUNT, no sampling. It works from reflected structure alone. This is verified by a test that captures every executed statement and asserts none read a user table. Use it when you may see a schema's shape but not its contents.
The analyzer also flags columns likely to hold personal data (email, name, address, and similar) from their names, so a schema review surfaces them. Because it is name-based, it works in metadata-only mode too. It is a checklist aid, not an authority.
Scope, deliberately
This is: a schema-adaptive generator of realistic relational test data, with reproducible output and generated code you own.
This is not: ML-based statistical synthesis, production-data masking, or an ETL pipeline. Those are different products with different risk profiles. This tool stays small enough that what it claims, it does every time.
Known limits, stated plainly:
- Entity classification is heuristic. Unrecognized tables still generate, just more plainly (see the fallback ladder).
- Columns whose name signals a date or timestamp are generated as dates even when loosely typed; a loosely typed column with a non-obvious name is generated as text, and generated code is deliberately easy to correct by hand.
- Uniqueness is enforced for well-known columns (email) but not yet for arbitrary unique or composite constraints.
- SQLite and PostgreSQL are the supported targets today. MySQL is roadmap.
Quality
- 403 tests, run on every push across Python 3.10, 3.11, and 3.12, on Linux and Windows, plus a PostgreSQL integration job against a real database.
- Coverage includes execution-level tests of the generated code itself, not just compilation: every template type is generated, executed, and checked for shape, nullability, referential integrity, and seed determinism.
- The suite encodes real found-the-hard-way regressions: cycle detection in dependency sorting, fallback-ladder observability, cross-process determinism, and Windows tempfile semantics.
Roadmap
- Constraint fidelity: arbitrary unique and composite keys, check constraints, tighter type mapping
- Streaming generation for large volumes, flat memory
- MySQL support; Parquet output
- PyPI release (until then, install from this repo as above)
History
Test Data Workbench is the third generation of a test-data tooling lineage; the first two generations were fixed-schema systems, and this one inverted the design to adapt to any schema it meets. It was built AI-accelerated with human-owned architecture; the original build prompt that seeded the system is preserved in docs/history/, and the full story is in the documentation.
License
Apache-2.0. Copyright Volantic Systems.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file test_data_workbench-1.0.0.tar.gz.
File metadata
- Download URL: test_data_workbench-1.0.0.tar.gz
- Upload date:
- Size: 153.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb0edf7adc74c23ec06ec105e38201592e572dda4a91204f765aba344b01cd15
|
|
| MD5 |
0c25e746d88a910da8097d3e03ac3b4e
|
|
| BLAKE2b-256 |
814b9d76aa78f372a051f15df3defdfd970a581e6cafda8f1ccd7db861d0a245
|
Provenance
The following attestation bundles were made for test_data_workbench-1.0.0.tar.gz:
Publisher:
publish.yml on VolanticSystems/test-data-workbench
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
test_data_workbench-1.0.0.tar.gz -
Subject digest:
cb0edf7adc74c23ec06ec105e38201592e572dda4a91204f765aba344b01cd15 - Sigstore transparency entry: 2194245169
- Sigstore integration time:
-
Permalink:
VolanticSystems/test-data-workbench@4a2ac500c4b44894fc612089daf59a95bd09a3c5 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/VolanticSystems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a2ac500c4b44894fc612089daf59a95bd09a3c5 -
Trigger Event:
release
-
Statement type:
File details
Details for the file test_data_workbench-1.0.0-py3-none-any.whl.
File metadata
- Download URL: test_data_workbench-1.0.0-py3-none-any.whl
- Upload date:
- Size: 95.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de4cb96ff1c24658e8108c6dc5728e1970ad1512ce809471d8663fb593b5bbbf
|
|
| MD5 |
7653d5f0feafd40ee731585beccb458b
|
|
| BLAKE2b-256 |
d7ce606a56c183cc95a02f26dfac7975563660366a1abc5608b59e021e36f331
|
Provenance
The following attestation bundles were made for test_data_workbench-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on VolanticSystems/test-data-workbench
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
test_data_workbench-1.0.0-py3-none-any.whl -
Subject digest:
de4cb96ff1c24658e8108c6dc5728e1970ad1512ce809471d8663fb593b5bbbf - Sigstore transparency entry: 2194245171
- Sigstore integration time:
-
Permalink:
VolanticSystems/test-data-workbench@4a2ac500c4b44894fc612089daf59a95bd09a3c5 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/VolanticSystems
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a2ac500c4b44894fc612089daf59a95bd09a3c5 -
Trigger Event:
release
-
Statement type: