Metadata-Version: 2.4
Name: test-data-workbench
Version: 1.0.0
Summary: Schema-adaptive test data generator: point it at a database, get realistic relational test data back
Project-URL: Homepage, https://github.com/VolanticSystems/test-data-workbench
Project-URL: Documentation, https://volanticsystems.github.io/test-data-workbench/
Project-URL: Repository, https://github.com/VolanticSystems/test-data-workbench
Project-URL: Issues, https://github.com/VolanticSystems/test-data-workbench/issues
Author: Volantic Systems
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: code-generation,database,faker,fixtures,sqlalchemy,synthetic-data,test-data,testing
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.10
Requires-Dist: aiofiles>=23.2.1
Requires-Dist: faker>=20.1.0
Requires-Dist: fastapi>=0.104.1
Requires-Dist: jinja2>=3.1.2
Requires-Dist: pandas>=2.1.3
Requires-Dist: pydantic>=2.5.0
Requires-Dist: pyyaml>=6.0.1
Requires-Dist: rich>=13.7.0
Requires-Dist: sqlalchemy>=2.0.23
Requires-Dist: uvicorn>=0.24.0
Provides-Extra: dev
Requires-Dist: httpx2; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.1; extra == 'dev'
Requires-Dist: pytest-mock>=3.12.0; extra == 'dev'
Requires-Dist: pytest>=7.4.3; extra == 'dev'
Provides-Extra: postgres
Requires-Dist: psycopg2-binary>=2.9.9; extra == 'postgres'
Description-Content-Type: text/markdown

# Test Data Workbench

[![CI](https://github.com/VolanticSystems/test-data-workbench/actions/workflows/ci.yml/badge.svg)](https://github.com/VolanticSystems/test-data-workbench/actions/workflows/ci.yml)
[![Docs](https://github.com/VolanticSystems/test-data-workbench/actions/workflows/docs.yml/badge.svg)](https://volanticsystems.github.io/test-data-workbench/)
![Python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)
![License](https://img.shields.io/badge/license-Apache--2.0-green)
![Tests](https://img.shields.io/badge/tests-403%20passing-brightgreen)

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.

<p align="center"><img src="https://raw.githubusercontent.com/VolanticSystems/test-data-workbench/main/docs/assets/tdw-demo.svg" alt="tdw demo: schema analysis, PII flagging, and generator deployment against a SQLite database"></p>

**Documentation:** https://volanticsystems.github.io/test-data-workbench/

## Quickstart

```bash
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:

```text
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](https://volanticsystems.github.io/test-data-workbench/).

## Architecture

```mermaid
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

1. Constraint fidelity: arbitrary unique and composite keys, check constraints, tighter type mapping
2. Streaming generation for large volumes, flat memory
3. MySQL support; Parquet output
4. 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/](docs/history/), and the full story is in the [documentation](https://volanticsystems.github.io/test-data-workbench/).

## License

Apache-2.0. Copyright Volantic Systems.
