ores.seeder

Table of Contents

1. Diagram

ores.seeder component diagram

Figure 1: ores.seeder

2. Summary

ores.seeder owns database-level synthetic test-data generation for ORE Studio. Its job is to emit SQL INSERT populate scripts that load hand-curated test rows into the schema at build time — so local development and CI start from a known, repeatable dataset without depending on real production data.

The first inhabitants are the Acme Corporation datasets, which exercise the domain schema (legal entities, books, portfolios). Future datasets follow the same convention under datasets/<name>/.

3. Distinct from siblings

Component Concern
ores.synthetic.service Synthetic data generated at C++ runtime, lives in-process
ores.codegen Source-code generation: SQL DDL, C++ types, CMake recipes
ores.seeder Synthetic data generated at build time, emitted as SQL `.sql` files

The split keeps the two synthetic-data concerns evolving independently — runtime data ships in the binary; seeder output ships as populate scripts loaded at DB setup.

4. MVP today: crafted JSON datasets

A crafted dataset is hand-curated content committed to disk under datasets/<name>/. Each dataset has:

  • One or more JSON files with the actual row data (e.g. country_currency.json — 100 country/currency pairs).
  • A model.json "batch driver" listing each artefact as (template, output, source) tuples.
  • A dataset_overview.org documenting the dataset (name, version, methodology, contents, see-also).
  • Optional companion files (e.g. methodology.txt).

The seeder is thin: seeder.sh delegates to ores.codegen.generator which renders the mustache templates (sql_catalog_populate.mustache, sql_country_populate.mustache, …) against each JSON. Templates *stay in ores.codegen/library/templates/= — the seeder does not own them.

5. Roadmap: synthesised flavour (not built)

The crafted form covers cases where rows are known and meaningful (an Acme book's currency mapping carries narrative weight). But many test-data needs are volume needs: 10,000 synthetic parties, 1,000 random trades, etc., where the shape matters but the specific values don't.

The codegen entity migrations have been preserving generator_expr column hints (std::string(faker::internet::url()) etc.) on entities, junctions, lookup entities. The synthesised flavour will read an entity overview (e.g. ores.refdata.party.org) and emit a Python+Faker script that produces N rows of SQL inserts. Same pipeline output (SQL populate), different source-of-truth (entity model + Faker hints, not hand-curated JSON).

Not built yet. No active use case forces it; the entity-model generator_expr hints are already in place so the substrate is ready when a use case appears.

6. Inputs

  • datasets/<name>/*.json — crafted row data, dataset metadata.
  • datasets/<name>/model.json — per-dataset batch driver (template → output → source-json).
  • projects/ores.codegen/library/templates/sql_*populate*.mustache — the rendering templates (delegated, not owned).

7. Outputs

  • projects/ores.sql/populate/<name>/*.sql — populate scripts that psql can run to seed the database.

8. Entry points

  • seeder.sh generate <dataset> — primary CLI; renders all artefacts declared in the dataset's model.json.
  • src/seeder.py — thin shim that imports codegen.generator.

9. Dependencies

  • ores.codegen — the renderer, load_data, mustache templates. ores.seeder delegates to it.

10. See also

Emacs 29.3 (Org mode 9.6.15)