Tutorial

Fremdschlüssel-konsistente Testdaten aus deinem Schema generieren

Zufällige Fake-Daten füllen Spalten. Sie respektieren keine Beziehungen. So bekommst du eine Datenbank, in der jeder Fremdschlüssel tatsächlich auflöst, aus einem SQL-, Django- oder Prisma-Schema, ladbar in Postgres oder MySQL ohne einen einzigen Constraint-Fehler.

SeedBase · ~6 Min. Lesezeit

Das Problem mit den meisten „Fake-Daten"

Greifst du zu einem generischen Daten-Faker, bekommst du in jeder Spalte realistisch aussehende Werte. Der Ärger beginnt bei den Beziehungen. Eine order_items-Zeile bekommt eine product_id von 4821, aber es gibt kein Produkt 4821. Lädst du das in eine echte Datenbank mit aktivierten Fremdschlüsseln, bricht es beim ersten INSERT ab:

ERROR:  insert or update on table "order_items" violates
        foreign key constraint "order_items_product_id_fkey"
DETAIL:  Key (product_id)=(4821) is not present in table "products".

Also deaktivierst du entweder die Constraints (und lieferst Daten aus, die in der Produktion nie existieren würden), oder du schreibst ein Seed-Skript von Hand, das den Abhängigkeitsgraphen selbst abläuft. Beides ist genau die Arbeit, die du vermeiden wolltest.

Was du eigentlich willst, sind Daten, die per Konstruktion referenziell konsistent sind: Kinder zeigen nur auf Eltern, die existieren, Inserts kommen in der richtigen Reihenfolge, und die Werteverteilungen sehen aus wie im echten Leben. So kommst du in wenigen Minuten dorthin.

Schritt 1: Dein Schema reingeben

SeedBase liest das Schema, das du ohnehin schon hast. Nimm das, was zu deinem Stack passt:

SQL (jede Datenbank)

Füg deine CREATE TABLE-Statements ein. Inline- und Tabellen-REFERENCES werden beide geparst:

CREATE TABLE products (
  id         SERIAL PRIMARY KEY,
  name       VARCHAR(255) NOT NULL,
  price      NUMERIC(10,2) NOT NULL
);

CREATE TABLE orders (
  id         SERIAL PRIMARY KEY,
  user_id    INTEGER NOT NULL REFERENCES users(id),
  status     VARCHAR(32) NOT NULL,
  total      NUMERIC(10,2) NOT NULL
);

CREATE TABLE order_items (
  id          SERIAL PRIMARY KEY,
  order_id    INTEGER NOT NULL REFERENCES orders(id),
  product_id  INTEGER NOT NULL REFERENCES products(id),
  quantity    INTEGER NOT NULL,
  unit_price  NUMERIC(10,2) NOT NULL
);

Django

Füg deine models.py ein, oder pushe dein ganzes Projekt aus dem VS-Code- oder PyCharm-Plugin. Der Parser folgt Djangos Vererbung: abstrakte Basisklassen mergen ihre Felder in jedes Kind, Mixins werden erkannt, der implizite id-Primärschlüssel wird ergänzt, und ForeignKey("self") wird zu einem selbstreferenzierenden Baum.

Prisma

Füg deine schema.prisma ein. Relationsfelder und @relation-Attribute werden zu Fremdschlüsseln; Skalarfelder behalten ihre Typen.

Kein Schema zur Hand? Starte mit der eingebauten E-Commerce-Vorlage und tausch später deine eigenen Tabellen ein. Du siehst trotzdem den kompletten Ablauf von Anfang bis Ende.

Schritt 2: Generieren

Auf Generieren klicken. Im Hintergrund erledigt SeedBase den Teil, der die Daten überhaupt erst ladbar macht:

Schritt 3: Realistisch machen, nicht nur valide

Valide Daten, die alle gleich aussehen, verstecken trotzdem Bugs. Ein paar Dinge, die SeedBase tut, damit die Daten sich wie Produktion verhalten:

Schritt 4: In deine Datenbank laden

Exportiere als SQL, CSV, JSON oder Parquet, oder pushe direkt in eine Verbindung. Weil die Inserts bereits in FK-Reihenfolge vorliegen, lädst du mit aktivierten Constraints, ganz ohne SET session_replication_role-Tricks:

# Postgres
psql "$DATABASE_URL" -f dataset.postgresql.sql

# MySQL
mysql -u user -p mydb < dataset.mysql.sql

Oder generiere aus der CLI / CI und spar dir die Datei ganz:

pip install seedbase
seedbase generate --project <id> --format sql --out dataset.sql

Schritt 5: Reproduzierbar machen

Die Generierung ist pro Seed deterministisch: derselbe Seed erzeugt dieselben Daten, sodass ein CI-Lauf reproduzierbar ist. Exportiere die Generierungs-Config als JSON und committe sie neben deinen Migrationen. Jeder im Team regeneriert denselben Datensatz aus demselben Schema.

Wo das hingehört. Das ist zum Befüllen einer Dev-Datenbank, von Staging, einer Demo oder eines CI-Containers mit einem kohärenten Datensatz. Für Objekt-Fixtures innerhalb eines einzelnen Testlaufs ist eine Per-Model-Factory weiterhin das richtige Werkzeug. Die zwei lösen unterschiedliche Probleme.

Das ist die ganze Schleife

Schema rein, generieren, laden. Die schwierigen Teile (Insert-Reihenfolge, jedes Auflösen jedes Fremdschlüssels, realistische Schiefe, kohärente abgeleitete Werte) sind erledigt, sodass du kein weiteres Seed-Skript von Hand schreibst. Getestet gegen ein echtes Django-Projekt mit 20 Apps und 226 Models, woher die meisten Edge Cases kamen.

Probier es an deinem eigenen Schema

Füg dein SQL, deine Django-Models oder dein Prisma-Schema ein und generiere eine befüllte, FK-konsistente Datenbank. Free-Tier, keine Kreditkarte.

  • Jeder FK löst auf
  • Realistische Verteilungen
  • SQL / CSV / JSON
  • EU-gehostet
Testdaten generieren, kostenlos

Nach Stack: Django · Prisma · SQL