Zum Inhalt

Datendefinitionsmodell – Kernelemente

Datendefinitionsmodelle sind grundlegend für die Testdatengenerierungsfunktionen von DATAMIMIC. Dieses Dokument behandelt die wichtigsten Elemente – wenn Du neu bei DATAMIMIC bist, beginne hier. Für fortgeschrittene Funktionen siehe Fortgeschrittene Datendefinitionselemente.

Überblick

Datendefinitionsmodelle legen fest, wie Testdaten generiert, transformiert oder maskiert werden sollen. Die Kernelemente ermöglichen es Dir:

  • Datengenerierungsaufgaben zu definieren
  • Schlüsselfelder und deren Werte zu spezifizieren
  • Variablen zu erstellen und zu verwenden
  • Strukturierte Datensätze zu generieren

Basiselemente

<setup>

Das <setup>-Element ist das Wurzelelement für alle Datengenerierungsaufgaben. Es enthält ein oder mehrere <generate>-Elemente, die spezifische Datengenerierungsoperationen definieren. Mehr zur Verwendung findest Du unter Konfigurationsmodelle.

1
2
3
4
5
<setup>
    <generate name="users" count="100">
        <!-- Details zur Generierung kommen hier hin -->
    </generate>
</setup>

<generate>

Das <generate>-Element ist das Herzstück der Datendefinitionsmodelle. Es definiert eine Datengenerierungsaufgabe und beinhaltet Attribute wie name, count und target. Mit diesem Element werden strukturierte Daten basierend auf den angegebenen Konfigurationen erstellt.

Attribute

  • name: Gibt den Namen der Generierungsaufgabe an.
  • count: Gibt die Anzahl der zu generierenden Datensätze an.
  • source: Gibt die Datenquelle an (z.B. data/active.ent.csv, mongo).
  • target: Gibt das Ziel der Ausgabe an (z.B. CSV, sqliteDB).
  • type: Gibt den Typ der zu generierenden Daten an.
  • cyclic: Aktiviert oder deaktiviert zyklische Generierung. Standard ist False.
  • selector: Gibt eine Datenbankabfrage für die Generierung an.
  • separator: Gibt einen Trenner für die generierten Daten an. Standard ist |.
  • sourceScripted: Aktiviert oder deaktiviert die skriptgesteuerte Auswertung der Quelle in der Quelldatei (z.B. example.ent.csv, example.json). Standard ist False.
  • pageSize: Gibt die Seitengröße für die Datengenerierung an.
  • storageId: Gibt die ID des Objektspeichers an, definiert durch das <object-storage>-Element.
  • sourceUri: Gibt die URI der Datenquelle im Objektspeicher an (z.B. datasource/employees.csv).
  • exportUri: Gibt die URI für den Export der generierten Daten im Objektspeicher an (z.B. export/product.csv).
  • container: Gibt den Containernamen für Azure Blob Storage an.
  • bucket: Gibt den Bucket-Namen für AWS S3 an.
  • distribution: Gibt die Verteilung der Datenquelleniteration an (z.B. random, ordered). Standard ist random.
  • converter: Gibt einen Konverter zur Wertetransformation an.
  • variablePrefix: Konfigurierbares Attribut, das das Präfix für Variablensubstitution in dynamischen Strings definiert (Standard ist __).
  • variableSuffix: Konfigurierbares Attribut, das das Suffix für Variablensubstitution in dynamischen Strings definiert (Standard ist __).
  • numProcess: Definiert die Anzahl der Prozesse für Multiprocessing, kann vom Elternelement <setup> übernommen werden. Standard ist 1.
  • mpPlatform: Definiert die Multiprocessing-Plattform. Zulässige Werte sind multiprocessing und ray. Standardwert ist multiprocessing.

Kindelemente

  • <key>: Gibt Schlüsselfelder innerhalb der Datengenerierungsaufgabe an.
  • <variable>: Definiert Variablen, die bei der Datengenerierung verwendet werden.
  • <reference>: Definiert Referenzen auf andere generierte Daten.
  • <nestedKey>: Gibt verschachtelte Schlüsselfelder und deren Generierungsmethoden an.
  • <list>: Definiert Listen von Datenelementen.
  • <condition>: Definiert eine Bedingung, um Daten nur dann einzufügen, wenn diese erfüllt ist.
  • <array>: Definiert Arrays von Datenelementen.
  • <echo>: Gibt Text oder Variablen zur Protokollierung oder zum Debugging aus.

Beispiel 1: Verwendung von Objektspeicher für die Datengenerierung

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<setup>
    <!-- Definiere object-storage mit ID, die auf die Umgebung verweist -->
    <object-storage id="aws"/>
    <!-- Schreibe Datei in den Objektspeicher -->
    <generate name="external_write" bucket="datamimic-01" storageId="aws" exportUri="/datamimic_exporting_result/" target="JSON, CSV, TXT, XML" count="100">
        <key name="id" generator="IncrementGenerator"/>
        <key name="name" type="string"/>
    </generate>
    <!-- Lese Datei aus dem Objektspeicher -->
    <generate name="external_read" bucket="datamimic-01" sourceUri="datamimic_exporting_result/external_write.json" source="aws" />
</setup>

Beispiel 2: Verwendung von selector mit einer Datenbank

1
2
3
4
<generate name="CUSTOMER" source="mongodb" selector="find: 'CUSTOMER', filter: {'age': {'$lt': 30}}" >
    <key name="id" generator="IncrementGenerator"/>
    <key name="name" type="string"/>
</generate>

In diesem Beispiel:

  • Der selector wird verwendet, um die MongoDB-Datenbank abzufragen und alle Kunden unter 30 Jahren zu finden.
  • Die Daten werden an den ConsoleExporter ausgegeben.

Beispiel 3: Datengenerierung mit MongoDB und Aggregation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<setup >
    <memstore id="mem"/>
    <mongodb id="mongodb"/>

    <!-- Lösche Sammlungen vor der Generierung neuer Daten -->
    <generate name="delete_users" source="mongodb" selector="find: 'more_users', filter: {}" target="mongodb.delete"/>
    <generate name="delete_orders" source="mongodb" selector="find: 'more_orders', filter: {}" target="mongodb.delete"/>
    <generate name="delete_products" source="mongodb" selector="find: 'more_products', filter: {}" target="mongodb.delete"/>

    <!-- Generiere Sammlungen für Bestellungen, Nutzer und Produkte -->
    <generate name="more_orders" source="script/orders.json" target="mongodb"/>
    <generate name="more_users" source="script/users.json" target="mongodb"/>
    <generate name="more_products" source="script/products.json" target="mongodb"/>

    <!-- Führe eine Aggregationsabfrage aus, um Nutzerbestellungen und Ausgaben zusammenzufassen -->
    <generate name="more_summary" count="20" >
        <variable name="result" source="mongodb"
                  selector='aggregate: "more_users",
                            pipeline: [
                              {
                                "$lookup": {
                                  "from": "more_orders",
                                  "localField": "user_id",
                                  "foreignField": "user_id",
                                  "as": "userOrders"
                                }
                              },
                              {
                                "$unwind": "$userOrders"
                              },
                              {
                                "$lookup": {
                                  "from": "more_products",
                                  "localField": "userOrders.order_item",
                                  "foreignField": "product_name",
                                  "as": "orderProducts"
                                }
                              },
                              {
                                "$unwind": "$orderProducts"
                              },
                              {
                                "$group": {
                                  "_id": "$user_id",
                                  "user_name": { "$first": "$user_name" },
                                  "order_items": { "$push": "$userOrders.order_item" },
                                  "quantities": { "$first": "$userOrders.quantity" },
                                  "total_spending": {
                                    "$sum": {
                                      "$multiply": ["$userOrders.quantity", "$orderProducts.price"]
                                    }
                                  }
                                }
                              }
                            ]'/>
        <nestedKey name="users_orders" script="result"/>
    </generate>

    <!-- Lösche Sammlungen nach der Generierung -->
    <generate name="delete_users" source="mongodb" selector="find: 'more_users', filter: {}" target="mongodb.delete"/>
    <generate name="delete_orders" source="mongodb" selector="find: 'more_orders', filter: {}" target="mongodb.delete"/>
    <generate name="delete_products" source="mongodb" selector="find: 'more_products', filter: {}" target="mongodb.delete"/>
</setup>

Beispiel 4: Datengenerierung mit Kafka

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<setup >
    <kafka-exporter id="kafkaLocal" environment="environment"/>
    <kafka-importer id="kafka_importer" system="kafkaLocal" enable.auto.commit="True" auto.offset.reset="earliest" group.id="datamimic" decoding="UTF-8" environment="environment"/>

    <!-- Setze Kafka-Topic zurück, indem alle Nachrichten konsumiert werden -->
    <generate name="reset" source="kafka_importer" type="kafka" count="100" target=""/>

    <!-- Generiere Daten für den Export nach Kafka und Konsole -->
    <generate name="exported_data" count="10" target="ConsoleExporter, kafkaLocal">
        <variable name="person" entity="Person"/>
        <key name="name" script="person.name"/>
        <key name="email" script="person.email"/>
    </generate>

    <!-- Importiere Daten aus Kafka -->
    <generate name="imported_data" source="kafka_importer" type="kafka" count="20"  distribution="ordered"/>
</setup>

Beispiel 5: Verwendung von Daten aus einer CSV-Datei

1
2
3
4
<setup defaultSeparator="|">
    <generate name="product1" source="data/products.ent.csv" separator=","  distribution="ordered"/>
    <generate name="product2" source="data/products_2.ent.csv"  distribution="ordered"/>
</setup>

In diesem Beispiel:

  • Zwei generate-Aufgaben werden erstellt, die Daten aus CSV-Dateien beziehen und an den ConsoleExporter ausgeben.

Beispiel 6: Verwendung von cyclic mit Daten aus dem Speicher

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<setup >
    <memstore id="mem"/>
    <generate name="product" count="15" target="mem">
        <key name="id" generator="IncrementGenerator"/>
        <key name="name" values="'Alice', 'Bob', 'Cameron'"/>
    </generate>

    <!-- Generiere 30 nicht-zyklische und zyklische Produkte aus dem Speicher -->
    <generate name="non-cyclic-product" type="product" count="30" cyclic="False" source="mem" target="" distribution="ordered"/>
    <generate name="cyclic-product" type="product" count="30" cyclic="True" source="mem" target="" distribution="ordered"/>
    <generate name="big-cyclic-product" type="product" count="100" cyclic="True" source="mem" target="" distribution="ordered"/>
</setup>

Beispiel 7: Verwendung von 'sourceScripted' mit JSON-Template

1
2
3
4
5
6
7
<setup>
    <generate name="json_data" source="script/data.json" sourceScripted="True" target="">
        <variable name="random_age" generator="IntegerGenerator(min=18, max=65)"/>
        <variable name="street_name" generator="StreetNameGenerator"/>
        <variable name="address_number" generator="IntegerGenerator"/>
    </generate>
</setup>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[
    {
        "id": 1,
        "name": "Alice",
        "age": "{random_age}",
        "address": "__address_number__, __street_name__ St"
    },
    {
        "id": 2,
        "name": "Bob",
        "age": "{random_age}",
        "address": "__address_number__, __street_name__ St"
    },
    {
        "id": 3,
        "name": "Cameron",
        "age": "{random_age}",
        "address": "__address_number__, __street_name__ St"
    }
]

Ergebnis:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[
    {
        "id": 1,
        "name": "Alice",
        "age": 23,
        "address": "801538, Walnut Street St"
    },
    {
        "id": 2,
        "name": "Bob",
        "age": 51,
        "address": "680286, View Street St"
    },
    {
        "id": 3,
        "name": "Cameron",
        "age": 29,
        "address": "711086, Forest Street St"
    }
]

In diesem Beispiel:

  • Das Attribut sourceScripted="True" wird verwendet, um das JSON-Template mit eingebetteten Variablen auszuwerten.
  • Das JSON-Template enthält Platzhalter für Variablen wie random_age, street_name und address_number.
  • Wenn der gesamte JSON-Feldwert eine Variable ist, sollte sie in geschweifte Klammern {} eingeschlossen werden (z.B. "age": "{random_age}"). Der zurückgegebene Wert kann ein String, Integer oder ein anderer Typ sein.
  • Wenn eine Variable in einen String eingebettet ist, sollte sie in doppelte Unterstriche __ eingeschlossen werden (z.B. "address": "__address_number__, __street_name__ St"). Der zurückgegebene Wert ist ein String. Du kannst das Präfix und Suffix für die Variablensubstitution auch mit den Attributen variablePrefix, variableSuffix, defaultVariablePrefix und defaultVariableSuffix anpassen. Zum Beispiel:
  •  1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    <setup defaultVariablePrefix="-%" defaultVariableSuffix="%-">
        <generate name="json_data" source="script/data.json" sourceScripted="True" target="">
            <variable name="random_age" generator="IntegerGenerator(min=18, max=65)"/>
        </generate>
    </setup>
    <setup>
        <generate name="json_data" source="script/data.json" sourceScripted="True" target="" variablePrefix="-%" variableSuffix="%-">
            <variable name="random_age" generator="IntegerGenerator(min=18, max=65)"/>
        </generate>
    </setup>
    

Beispiel 8: Verwendung der Multiprocessing-Plattform ray

1
2
3
4
5
6
7
<setup>
    <generate name="json_data" count="1000000" mpPlatform="ray" target="">
        <key name="random_age" generator="IntegerGenerator(min=18, max=65)"/>
        <key name="street_name" generator="StreetNameGenerator"/>
        <key name="address_number" generator="IntegerGenerator"/>
    </generate>
</setup>
In diesem Beispiel: - Generierungsaufgaben werden mit der Plattform ray statt mit dem Standard-Python-Multiprocessing ausgeführt.


Das <generate>-Element definiert eine Datengenerierungsaufgabe. Im einfachsten Fall benötigt es:

  • name: Identifiziert die Generierungsaufgabe
  • count: Gibt an, wie viele Datensätze generiert werden sollen
  • target: (Optional) Gibt das Ausgabeformat an (z.B. CSV, JSON)

Einfaches Beispiel

1
2
3
4
5
6
7
<setup>
    <generate name="simple_users" count="10" target="CSV">
        <key name="id" generator="IncrementGenerator"/>
        <key name="name" type="string"/>
        <key name="age" type="int"/>
    </generate>
</setup>

Wesentliche Attribute

  • name: Aufgabenbezeichner
  • count: Anzahl der zu generierenden Datensätze
  • target: Ausgabeformat (z.B. CSV, JSON, ConsoleExporter)
  • source: (Optional) Eingabedatenquelle

<key>

Das <key>-Element definiert Schlüsselfelder innerhalb einer Datengenerierungsaufgabe und legt deren Generierungsmethoden fest. Diese Felder sind entscheidend für die Erstellung eindeutiger Kennungen oder strukturierter Elemente in den generierten Daten. Das <key>-Element ermöglicht dynamische, konstante oder bedingte Datengenerierung und bietet verschiedene Attribute zur Anpassung des Verhaltens.

Attribute

  • name: Gibt den Namen des Schlüssels an. Dies ist verpflichtend und wird als Feldname in den generierten Daten verwendet.
  • type: Definiert den Datentyp des Schlüssels (z.B. string, int, bool). Dies ist optional, wenn script oder generator verwendet wird.
  • source: Gibt die Datenquelle für den Schlüssel an (z.B. eine Datenbank, eine Datei).
  • separator: Gibt einen Trenner für CSV-Quellen an.
  • values: Stellt eine Liste statischer Werte bereit, aus denen der Schlüssel ausgewählt werden kann.
  • script: Definiert ein Skript zur dynamischen Generierung des Schlüsselwerts.
  • generator: Gibt einen Generator zur automatischen Wertgenerierung an (z.B. RandomNumberGenerator, IncrementGenerator).
  • constant: Definiert einen konstanten Wert für den Schlüssel.
  • condition: Gibt eine Bedingung an, die bestimmt, ob der Schlüssel generiert wird.
  • converter: Gibt einen Konverter zur Wertetransformation an (z.B. Datumsumwandlung, Formatänderungen).
  • pattern: Definiert ein Regex-Muster zur Validierung des Schlüsselwerts.
  • inDateFormat / outDateFormat: Gibt Eingabe- und Ausgabeformate für Datumsumwandlungen an.
  • defaultValue: Gibt einen Standardwert an, falls der Wert des Schlüssels null ist oder nicht generiert wird.
  • nullQuota: Definiert die Wahrscheinlichkeit, dass der Schlüssel einen Nullwert erhält. Standard ist 0 (niemals null).
  • database: Gibt die Datenbank an, die zur Wertgenerierung verwendet wird (z.B. SequenceTableGenerator).
  • string: Attribut zur Generierung komplexer Strings durch Einbetten von Variablen mit anpassbaren Trennzeichen (siehe Variablen-Abschnitt).
  • variablePrefix: Konfigurierbares Attribut, das das Präfix für Variablensubstitution in dynamischen Strings definiert (Standard ist __).
  • variableSuffix: Konfigurierbares Attribut, das das Suffix für Variablensubstitution in dynamischen Strings definiert (Standard ist __).

Beispiel 1: Generierung von konstanten und geskripteten Schlüsseln

1
2
3
4
5
6
<setup>
    <generate name="static_and_scripted_keys" count="5" >
        <key name="static_key" constant="fixed_value"/>
        <key name="dynamic_key" script="random.randint(1, 100)"/>
    </generate>
</setup>

In diesem Beispiel:

  • static_key erhält für jeden Datensatz den konstanten Wert "fixed_value".
  • dynamic_key generiert für jeden Datensatz mit einem Skript eine Zufallszahl zwischen 1 und 100.

Beispiel 2: Umgang mit nullQuota für optionale Felder

1
2
3
4
5
6
7
<setup>
    <generate name="nullable_keys" count="10">
        <key name="key_always_null" type="string" nullQuota="1"/> <!-- 100% Nullwerte -->
        <key name="key_never_null" type="string" nullQuota="0"/> <!-- 0% Nullwerte -->
        <key name="key_sometimes_null" type="string" nullQuota="0.5"/> <!-- 50% Nullwerte -->
    </generate>
</setup>

In diesem Beispiel:

  • key_always_null hat immer einen Nullwert (nullQuota="1").
  • key_never_null hat nie einen Nullwert (nullQuota="0").
  • key_sometimes_null hat in 50% der Fälle einen Nullwert (nullQuota="0.5").

Beispiel 3: Verwendung von defaultValue als Fallback

1
2
3
4
5
6
7
<setup>
    <generate name="default_values" count="5">
        <key name="key_with_empty_string" script="" defaultValue="default_value"/> <!-- Fallback auf default_value -->
        <key name="key_with_none" script="None" defaultValue="default_value"/> <!-- Fallback auf default_value -->
        <key name="key_with_condition" script="" defaultValue="default_value" condition="False"/> <!-- Bedingung False, keine Generierung -->
    </generate>
</setup>

Hier:

  • Die ersten beiden Schlüssel greifen auf ihren defaultValue zurück, wenn das Skript einen leeren oder None-Wert erzeugt.
  • Der dritte Schlüssel wird nicht generiert, da seine Bedingung False ist.

Beispiel 4: Bedingte Schlüsselerzeugung

1
2
3
4
5
6
<setup>
    <generate name="conditional_keys" count="10">
        <key name="conditional_key" script="random.randint(1, 100)" condition="random.randint(1, 100) > 50"/>
        <key name="constant_key" constant="fixed_value" condition="True"/>
    </generate>
</setup>

In diesem Beispiel:

  • conditional_key wird nur generiert, wenn eine Zufallszahl größer als 50 ist.
  • constant_key wird immer generiert, da die Bedingung True ist.

Beispiel 5: Verwendung von pattern zur Validierung

1
2
3
4
5
6
<setup>
    <generate name="pattern_matching" count="10">
        <key name="email" script="'[email protected]'" pattern="^[\w\.-]+@[\w\.-]+\.\w+$"/>
        <key name="phone_number" script="'123-456-7890'" pattern="^\d{3}-\d{3}-\d{4}$"/>
    </generate>
</setup>

In diesem Beispiel:

  • Der Wert des Schlüssels email muss dem Regex-Muster für eine gültige E-Mail-Adresse entsprechen.
  • Der Wert des Schlüssels phone_number muss dem Regex-Muster für eine gültige Telefonnummer entsprechen (123-456-7890).

Beispiel 6: Datumsumwandlung mit inDateFormat und outDateFormat

1
2
3
4
5
<setup>
    <generate name="date_format_conversion" count="10">
        <key name="date_of_birth" script="'2023-10-12'" inDateFormat="%Y-%m-%d" outDateFormat="%d-%m-%Y"/>
    </generate>
</setup>

In diesem Beispiel:

  • Der Schlüssel date_of_birth verwendet das Eingabeformat (inDateFormat="%Y-%m-%d"), um das Datum zu parsen, und wandelt es in das angegebene Ausgabeformat (outDateFormat="%d-%m-%Y") um.

Beispiel 7: Schlüsselerzeugung mit SequenceTableGenerator

1
2
3
4
5
6
<setup>
    <database id="sourceDB" system="postgres"/>
    <generate name="sequence_key_generation" count="10" >
        <key name="user_id" database="sourceDB" generator="SequenceTableGenerator"/>
    </generate>
</setup>

Hier:

  • Der Schlüssel user_id wird mit einem SequenceTableGenerator aus einer PostgreSQL-Datenbank generiert.
  • Dieser Generator stellt sicher, dass eindeutige, fortlaufende Werte aus der Datenbank gezogen werden.

Best Practices für die Verwendung von <key>

  1. Nutze script für dynamische Werte: Verwende Skripte, um komplexe und dynamische Werte zu generieren, z.B. Zufallszahlen, Daten oder berechnete Werte.
  2. Setze nullQuota für realistische Daten ein: Simuliere reale Szenarien, in denen manche Schlüssel Nullwerte haben.
  3. Fallback mit defaultValue: Stelle sicher, dass Schlüssel immer einen Wert haben, falls ein Skript fehlschlägt oder None liefert.
  4. Musterabgleich zur Validierung: Nutze das Attribut pattern, um bestimmte Formate zu erzwingen, z.B. E-Mail-Adressen oder Telefonnummern.
  5. Steuere die Schlüsselerzeugung mit condition: Bestimme dynamisch, ob ein Schlüssel generiert werden soll, um komplexe Szenarien abzubilden.

<variable>

Das <variable>-Element definiert Variablen, die in Datengenerierungsaufgaben verwendet werden. Variablen können aus Datenbanken, Datensätzen oder dynamisch per Skript generiert werden. Sie ermöglichen flexible und dynamische Testdaten, indem sie steuern, wie Daten abgerufen oder iteriert werden.

Attribute

  • name: Gibt den Namen der Variablen an.
  • type: Definiert den Datentyp der Variablen (optional).
  • source: Gibt die Datenquelle für die Variable an (z.B. eine Datenbank oder eine Datei).
  • selector: Definiert eine Abfrage, um Daten für die Variable aus einer Datenbank zu holen (einmalig ausgeführt).
  • iterationSelector: Führt bei jeder Iteration eine Abfrage aus, um dynamische Daten für die Variable zu holen.
  • separator: Gibt einen Trenner für die Variable an (z.B. für CSV-Quellen).
  • cyclic: Aktiviert oder deaktiviert zyklische Iteration der Datenquelle.
  • entity: Definiert die Entität zur Datengenerierung (z.B. ein vordefiniertes Modell oder Objekt).
  • script: Gibt ein Skript zur dynamischen Generierung des Variablenwerts an.
  • weightColumn: Gibt eine Spalte zur Gewichtung der Datenauswahl an (typischerweise bei CSV- oder Datenbankquellen).
  • sourceScripted: Bestimmt, ob die Quelle geskriptet ist.
  • generator: Definiert einen Generator für die Variable (z.B. RandomNumberGenerator, IncrementGenerator).
  • dataset: Gibt den Datensatz für die Variable an (meist ein Dateipfad).
  • locale: Definiert das Locale für die Datengenerierung.
  • inDateFormat / outDateFormat: Gibt Datumsumwandlung für Eingabe und Ausgabe an.
  • converter: Definiert einen Konverter zur Wertetransformation.
  • constant: Setzt einen festen Wert für die Variable.
  • values: Stellt eine Liste von Werten bereit, aus denen die Variable ausgewählt werden kann.
  • defaultValue: Setzt einen Standardwert, wenn keine Daten verfügbar sind.
  • pattern: Definiert ein Regex-Muster zur Validierung des Variableninhalts.
  • distribution: Steuert die Auswahl der Datenquelle (random, ordered).
  • database: Gibt die Datenbank für die Generierung an.
  • string: Attribut zur Generierung komplexer Strings durch Einbetten von Variablen mit anpassbaren Trennzeichen.
  • variablePrefix: Konfigurierbares Attribut, das das Präfix für Variablensubstitution in dynamischen Strings definiert (Standard ist __).
  • variableSuffix: Konfigurierbares Attribut, das das Suffix für Variablensubstitution in dynamischen Strings definiert (Standard ist __).

Beispiel 1: Verwendung von generator für fortlaufende Werte

1
2
3
4
5
6
<setup>
    <generate name="sequential_ids" count="10" >
        <variable name="id" generator="IncrementGenerator"/>
        <key name="generated_id" script="id"/>
    </generate>
</setup>

In diesem Beispiel:

  • Die Variable id verwendet den IncrementGenerator, der fortlaufende Zahlen generiert.
  • Die generierte ID wird für jeden Datensatz dem Schlüssel generated_id zugewiesen.

Beispiel 2: Daten aus einer CSV-Datei mit separator

1
2
3
4
5
6
7
8
<setup>
    <generate name="person_data" count="5" >
        <variable name="person" source="data/people.csv" separator="," distribution="ordered"/>
        <key name="person_id" script="person.id"/>
        <key name="person_name" script="person.name"/>
        <key name="person_age" script="person.age"/>
    </generate>
</setup>

In diesem Beispiel:

  • Die Variable person wird aus einer CSV-Datei bezogen, die Felder sind durch Kommas getrennt.
  • distribution="ordered" sorgt dafür, dass die Datensätze in der Reihenfolge der Datei verarbeitet werden.

Beispiel 3: Definition einer konstanten Variable

1
2
3
4
5
6
<setup>
    <generate name="constant_value_example" count="3" >
        <variable name="country" constant="Germany"/>
        <key name="user_country" script="country"/>
    </generate>
</setup>

In diesem Fall:

  • Die Variable country ist als Konstante mit dem Wert "Germany" definiert.
  • Dieser Wert wird jedem generierten Datensatz im Schlüssel user_country zugewiesen.

Beispiel 4: Dynamische Variablen mit script generieren

1
2
3
4
5
6
7
8
<setup>
    <generate name="dynamic_variables" count="5" >
        <variable name="random_number" script="random.randint(1, 100)"/>
        <variable name="full_name" script="fake.name()"/>
        <key name="random_number_value" script="random_number"/>
        <key name="full_name_value" script="full_name"/>
    </generate>
</setup>

In diesem Beispiel:

  • Die Variable random_number generiert per Skript eine Zufallszahl zwischen 1 und 100.
  • Die Variable full_name verwendet die Bibliothek fake, um zufällige Namen zu generieren.
  • Diese Werte werden für jeden Datensatz ausgegeben.

Beispiel 5: Zyklische Variablen mit einer CSV-Quelle

1
2
3
4
5
6
7
<setup>
    <generate name="cyclic_people" count="8" >
        <variable name="person" source="data/people.csv" cyclic="True" separator=","/>
        <key name="person_id" script="person.id"/>
        <key name="person_name" script="person.name"/>
    </generate>
</setup>

In diesem Beispiel:

  • Das Attribut cyclic="True" sorgt dafür, dass nach Verbrauch aller Datensätze aus der CSV-Datei von vorne begonnen wird.

Beispiel 6: Verwendung von distribution zur Zufallsauswahl

1
2
3
4
5
6
7
<setup>
    <generate name="random_people" count="10" >
        <variable name="person" source="data/people.csv" separator="," distribution="random"/>
        <key name="person_id" script="person.id"/>
        <key name="person_name" script="person.name"/>
    </generate>
</setup>

Hier: - Das Attribut distribution="random" sorgt dafür, dass die Datensätze zufällig aus der CSV-Datei ausgewählt werden.

Beispiel 7: Iteration mit iterationSelector

1
2
3
4
5
6
7
8
9
<setup>
    <generate name="iterate_selector" count="20" >
        <key name="iteration_count" generator="IncrementGenerator"/>
        <variable name="user" source="dbPostgres"
                  iterationSelector="SELECT id, name FROM users WHERE id = __iteration_count__"/>
        <key name="user_id" script="user[0].id"/>
        <key name="user_name" script="user[0].name"/>
    </generate>
</setup>

In diesem Beispiel:

  • Die Abfrage iterationSelector holt für jede Iteration Daten aus einer PostgreSQL-Datenbank, basierend auf dem Wert von iteration_count.

Beispiel 8: Gewichtete Variablen mit weightColumn

1
2
3
4
5
6
7
<setup>
    <generate name="weighted_people" count="10" >
        <variable name="people" source="data/people_weighted.csv" weightColumn="weight" separator=","/>
        <key name="person_id" script="people.id"/>
        <key name="person_name" script="people.name"/>
    </generate>
</setup>

Hier:

  • Das Attribut weightColumn="weight" steuert, wie häufig jede Zeile ausgewählt wird. Zeilen mit höherem Gewicht werden häufiger gewählt.

Beispiel 9: Variablen mit verschachtelten Schlüsseln kombinieren

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<setup>
    <generate name="customer_info" count="10" >
        <variable name="customer" source="data/customers.csv" cyclic="True"/>
        <variable name="notification" source="data/notifications.csv" cyclic="True"/>
        <key name="customer_id" script="customer.id"/>
        <key name="customer_name" script="customer.name"/>
        <nestedKey name="notifications" type="list" count="2">
            <key name="notification_type" script="notification.type"/>
            <key name="notification_message" script="notification.message"/>
        </nestedKey>
    </generate>
</setup>

In diesem Fall:

  • Die Variablen customer und notification werden aus CSV-Dateien bezogen.
  • Das nestedKey-Element generiert zwei Benachrichtigungen pro Kunde und zeigt, wie Variablen mit verschachtelten Strukturen kombiniert werden können.

Beispiel 10: Arbeiten mit Entitäten und länderspezifischen Daten

1
2
3
4
5
6
7
<setup>
    <generate name="localized_data" count="5" >
        <variable name="person" entity="Person" locale="de_DE"/>
        <key name="person_name" script="person.full_name"/>
        <key name="person_address" script="person.address"/>
    </generate>
</setup>

In diesem Beispiel:

  • Die Variable person wird mit der Entität Person generiert, wobei das Locale auf de_DE (Deutschland) gesetzt ist.
  • So können länderspezifische Daten wie Namen und Adressen erzeugt werden.

Beispiel 11: Verwendung des string-Attributs für dynamische und komplexe Strings

1
2
3
4
5
6
<setup defaultVariablePreffix="%%" defaultVariableSuffix="%%">
    <generate name="query_generation" count="1">
        <variable name="collection" constant="'users'" />
        <key name="query" string="find: %%collection%%, filter: {'status': 'active'}" />
    </generate>
</setup>

In diesem Beispiel:

  • Das Attribut string ermöglicht das direkte Einfügen der Variablen collection in die Abfrage.
  • Das benutzerdefinierte Präfix und Suffix %% ersetzt die Standard-Unterstriche.

Beispiel 12: Standard-variablePrefix und variableSuffix

1
2
3
4
5
6
<setup>
    <generate name="query_generation" count="1">
        <variable name="collection" constant="'users'" />
        <key name="query" string="find: __collection__, filter: {'status': 'active'}" />
    </generate>
</setup>

In diesem Fall: - Die Standard-Trennzeichen __ werden für die Variablensubstitution verwendet.

Zentrale Vorteile des string-Attributs

  • Einfachheit: Variablen können direkt im String eingebettet werden, ohne dass Verkettung oder Escape-Zeichen nötig sind.
  • Lesbarkeit: Dynamische Strings sind leichter zu lesen und zu pflegen.
  • Flexibilität: Die Attribute variablePrefix und variableSuffix erlauben die Anpassung der verwendeten Trennzeichen und bieten so mehr Flexibilität bei unterschiedlichen Syntaxen.

Best Practices für die Verwendung von <variable>

  1. Dynamische Datengenerierung: Nutze Skripte in Variablen, um dynamische Daten wie Zufallszahlen, Namen und Adressen zu erzeugen (z.B. mit random und fake).
  2. Zyklisch vs. nicht-zyklisch: Verwende zyklische Variablen, wenn Daten wiederholt werden sollen, nicht-zyklische werden nach einmaligem Durchlauf erschöpft.
  3. Gewichtung und Zufallsauswahl: Nutze weightColumn für gewichtete Auswahl und distribution="random" für zufällige Auswahl.
  4. Kombination mit verschachtelten Schlüsseln: Variablen können mit nestedKey kombiniert werden, um strukturierte, hierarchische Daten zu erzeugen.

<ml-train>

Das <ml-train>-Element wird verwendet, um Machine-Learning-Modelle mit Eingabedaten zu trainieren. Diese trainierten Modelle können dann als Quellen in <generate>-Elementen verwendet werden, um Originaldaten anzureichern. Das <ml-train>-Element ist ein Kindelement von <setup>.

Attribute

  • name: Gibt den Namen des Modells nach dem Training an. Dies ist verpflichtend und wird zur Referenzierung in anderen Elementen verwendet.
  • source: Gibt die Datenquelle an (z.B. data/active.ent.csv, mongo).
  • type: Gibt den Typ der zu generierenden Daten an.
  • mode: Gibt den Trainingsmodus an. Aktuell gibt es 'default' und 'persist'. 'default' entfernt das Modell nach Abschluss aller Aufgaben, 'persist' behält das Modell bei.
  • maxTrainingTime: Gibt die maximale Trainingszeit in Minuten an (z.B. 1, 5, 10).
  • separator: Gibt den Trenner der Quelldatei an (z.B. ',' für CSV-Dateien).

Beispiel 1: Einfaches Modelltraining

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<setup>
    <ml-train name="customer_csv_gen"
            source="data/customer.ent.csv"
            maxTrainingTime="1"
            separator=","/>

    <generate name="csv_customer" count="10000" pageSize="1000" source="customer_csv_gen" target="CSV">
        <key name="id" generator="IncrementGenerator"/>
    </generate>
</setup>

In diesem Beispiel: - Das Modell "customer_csv_gen" wird mit Daten aus "data/customers.csv" trainiert. - Der Modus ist nicht explizit angegeben, daher wird das Modell nach Abschluss entfernt. - Die CSV-Datei verwendet Komma als Trenner. - "generate" verwendet das trainierte Modell als Quelle zur Datengenerierung.

Beispiel 2: Training mit Persistenzmodus

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<setup numProcess="2">

    <ml-train name="customer_csv_gen"
              source="data/customer.ent.csv"
              mode="persist"
              maxTrainingTime="1"/>

    <!-- Generiere synthetische CUSTOMER-Datensätze mit dem ML-Generator -->
    <generate name="csv_customer" count="10000" pageSize="1000" source="customer_csv_gen" target="CSV">
        <key name="id" generator="IncrementGenerator"/>
    </generate>
</setup>

In diesem Beispiel: - Der Modus ist auf "persist" gesetzt, das Modell bleibt nach Abschluss erhalten. - Es kann später ohne erneutes Training verwendet werden.

1
2
3
4
5
<setup numProcess="2">
    <generate name="csv_customer" count="10000" pageSize="1000" source="customer_csv_gen" target="CSV">
        <key name="id" generator="IncrementGenerator"/>
    </generate>
</setup>

Komplettes Basisbeispiel

Hier ein vollständiges Beispiel, das die Kernelemente kombiniert:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<setup>
    <generate name="user_data" count="100" target="CSV">
        <!-- Definiere Variablen -->
        <variable name="person" entity="Person"/>

        <!-- Definiere Schlüssel -->
        <key name="id" generator="IncrementGenerator"/>
        <key name="first_name" script="person.given_name"/>
        <key name="last_name" script="person.family_name"/>
        <key name="age" type="int" generator="IntegerGenerator(min=18, max=80)"/>
        <key name="status" constant="active"/>
    </generate>
</setup>

Dies generiert 100 Benutzerdatensätze mit konsistenten, strukturierten Daten inklusive IDs, Namen, Alter und einem Statusfeld.

Nächste Schritte

Sobald Du mit diesen Kernelementen vertraut bist, schaue Dir die Fortgeschrittenen Datendefinitionselemente für komplexere Funktionen an, wie:

  • Verschachtelte Datenstrukturen
  • Bedingte Generierung
  • Komplexe Datenmuster
  • Arrays und Listen
  • Erweiterte Variablenverwendung