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.
Schritt 2: Generieren
Auf Generieren klicken. Im Hintergrund erledigt SeedBase den Teil, der die Daten überhaupt erst ladbar macht:
- Topologische Insert-Reihenfolge. Eltern vor Kindern, damit
productsundusersexistieren, bevororderskommt, undordersvororder_items. - Fremdschlüssel lösen auf. Jede
product_idzeigt auf ein Produkt, das tatsächlich generiert wurde, gewählt aus den bereits existierenden Zeilen, nicht eine zufällige Zahl. - Selbstreferenzen werden zu Bäumen. Eine
parent_idauf derselben Tabelle referenziert eine frühere Zeile; nullbare Self-FKs bekommen NULL-Wurzeln. Keine Vorwärtsreferenzen.
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:
- Schiefe Verteilungen. Nicht jeder User hat genau fünf Bestellungen. Ein Long-Tail bedeutet, mancher hat zwei und mancher neunzehn, und genau dort brechen Pagination und N+1-Queries.
- Kohärente Werte. Der Name einer Person passt zu ihrer E-Mail (
alex.miller@…für Alex Miller), undorder.totalentspricht der Summe seiner Positionen. Abgeleitete und denormalisierte Werte werden nach der Generierung rekonziliert, nicht unabhängig gewürfelt. - Sinnvolle Bereiche.
quantityist eine kleine Zahl, nicht 9.000. Der Bestellstatus kommt auspending / paid / shipped / delivered, nicht aus einem generischen Enum. - Zeitbewusste Zeitstempel.
created_atliegt immer vorupdated_at, und Zeitstempel werden relativ zu heute generiert, sodass „letzte 30 Tage"-Dashboards befüllt bleiben, während der Datensatz altert.
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.
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