Home Up PDF Prof. Dr. Ingo Claßen
Edurel Code - DMDB

Installation / Import

Installation von Edurel

!pip install edurel

Import von Edurel

from edurel.core.er_schema_man import ERSchemaMan
from edurel.core.rel_schema_man import RelSchemaMan
from edurel.core.duckdb_man import DuckDbMan
from edurel.utils.md import display_sql, display_md, display_yaml
from edurel.utils.sql import transpile_postgres_sql, validate_postgres_sql
from edurel.llm.conversation_rel import DataGenConversation, SQLGenConversation
from edurel.llm.conversation_er import ERRequirementsConversation, ERDesignConversation

Entitätstyp

er_yaml = """
entities:
- entityname: Lehrperson
  key: LPID
  attributes:
  - attributename: Name
    type: VARCHAR(100)
  - attributename: EMail
    type: VARCHAR(100)
    nullable: True
"""
erman = ERSchemaMan.fromStr(er_yaml)
erman.display_mermaid_diagram(direction="LR", height="200px")
relman = RelSchemaMan.fromAST(erman.get_rel())
relman.display_mermaid_diagram(direction="LR", height="200px")
display_sql(relman.get_sql())



CREATE TABLE Lehrperson (
  LPID INTEGER NOT NULL,
  Name VARCHAR(100) NOT NULL,
  EMail VARCHAR(100),
  PRIMARY KEY (LPID)
);

Beziehungstyp

er_yaml = """
entities:
- entityname: Lehrperson
  key: LPID
  attributes:
  - attributename: Name
    type: VARCHAR(100)
  - attributename: EMail
    type: VARCHAR(100)
    nullable: True

- entityname: Gebaeude
  key: GID
  attributes:
  - attributename: Bez
    type: VARCHAR(50)

relationships:
- relationshipname: hat_buero_in
  entities:
  - targetentity: Lehrperson
    cardinality: OPTIONAL_MANY
  - targetentity: Gebaeude
    cardinality: OPTIONAL_ONE
"""
erman = ERSchemaMan.fromStr(er_yaml)
erman.display_mermaid_diagram(direction="LR", height="200px")
relman = RelSchemaMan.fromAST(erman.get_rel())
relman.display_mermaid_diagram(direction="LR", height="300px")
display_sql(relman.get_sql())



CREATE TABLE Lehrperson (
  LPID INTEGER NOT NULL,
  Name VARCHAR(100) NOT NULL,
  EMail VARCHAR(100),
  GID INTEGER,
  PRIMARY KEY (LPID)
);
CREATE TABLE Gebaeude (
  GID INTEGER NOT NULL,
  Bez VARCHAR(50) NOT NULL,
  PRIMARY KEY (GID)
);
ALTER TABLE Lehrperson
  ADD CONSTRAINT fk_hat_buero_in FOREIGN KEY (GID) REFERENCES Gebaeude (GID);

Werteliste

er_yaml = """
entities:
- entityname: Modul
  key: MID
  attributes:
  - attributename: Bez
    type: VARCHAR(50)
valuelists:
- valuelistname: Modulart
  values:
  - Pflicht
  - Wahlpflicht
  - Wahl
  many_to_one_from_entities:
  - sourceentity: Modul
"""
erman = ERSchemaMan.fromStr(er_yaml)
erman.display_mermaid_diagram(direction="TB", height="200px")
relman = RelSchemaMan.fromAST(erman.get_rel())
relman.display_mermaid_diagram(direction="LR", height="250px")
display_sql(relman.get_sql())



CREATE TABLE Modul (
  MID INTEGER NOT NULL,
  Bez VARCHAR(50) NOT NULL,
  ModulartID INTEGER NOT NULL,
  PRIMARY KEY (MID)
);
CREATE TABLE Modulart (
  ID INTEGER NOT NULL,
  Description VARCHAR(100) NOT NULL,
  IsValid INTEGER NOT NULL,
  SortOrder INTEGER NOT NULL,
  PRIMARY KEY (ID)
);
ALTER TABLE Modul
  ADD CONSTRAINT fk_Modul_Modulart FOREIGN KEY (ModulartID) REFERENCES Modulart (ID);
INSERT INTO Modulart (ID, Description, IsValid, SortOrder) VALUES (1, 'Pflicht', 1, 1);
INSERT INTO Modulart (ID, Description, IsValid, SortOrder) VALUES (2, 'Wahlpflicht', 1, 2);
INSERT INTO Modulart (ID, Description, IsValid, SortOrder) VALUES (3, 'Wahl', 1, 3);

Assoziationstypen

er_yaml = """
entities:
- entityname: Kunde
  key: KID
  attributes:
  - attributename: Name
    type: VARCHAR(100)

- entityname: Kundenkategorie
  key: KKID
  attributes:
  - attributename: Bez
    type: VARCHAR(30)
  - attributename: BeginGueltig
    type: DATE
  - attributename: EndeGueltig
    type: DATE

- entityname: Lieferant
  key: LID
  attributes:
  - attributename: Name
    type: VARCHAR(100)

- entityname: Artikel
  key: AID
  attributes:
  - attributename: Bez
    type: VARCHAR(200)


associative_entities:
- associationname: Bestellung
  identification:
    localkey: BID
    keytype: INTEGER
  associations:
    - targetentity: Kunde
      cardinality: OPTIONAL_ONE
  attributes:
  - attributename: BestellDatum
    type: DATE

- associationname: Bestellposition
  identification:
    localkey: LfdNr
    keytype: INTEGER
    global:
    - targetentity: Bestellung
  associations:
    - targetentity: Artikel
      cardinality: OPTIONAL_ONE
  attributes:
  - attributename: Menge
    type: INTEGER

- associationname: Verkaufkondition
  identification:
    global:
    - targetentity: Kundenkategorie
      role: fuer_KK
    - targetentity: Artikel
      role: VK_Artikel
  attributes:
  - attributename: Preis
    type: DECIMAL(9,2)

- associationname: Einkaufskondition
  identification:
    global:
    - targetentity: Lieferant
      role: fuer_Lieferant
    - targetentity: Artikel
      role: EK_Artikel
  attributes:
  - attributename: DauerInTagen
    type: INTEGER
  - attributename: Preis
    type: DECIMAL(9,2)

relationships:
- relationshipname: hat_Kategorie
  entities:
  - targetentity: Kunde
    cardinality: MANY
  - targetentity: Kundenkategorie
    cardinality: OPTIONAL_ONE
"""
erman = ERSchemaMan.fromStr(er_yaml)
erman.display_mermaid_diagram(direction="RL", height="600px")
relman = RelSchemaMan.fromAST(erman.get_rel())
relman.display_mermaid_diagram(direction="RL", height="700px")
display_sql(relman.get_sql())



CCREATE TABLE Kunde (
  KID INTEGER NOT NULL,
  Name VARCHAR(100) NOT NULL,
  KKID INTEGER NOT NULL,
  PRIMARY KEY (KID)
);
CREATE TABLE Kundenkategorie (
  KKID INTEGER NOT NULL,
  Bez VARCHAR(30) NOT NULL,
  BeginGueltig DATE NOT NULL,
  EndeGueltig DATE NOT NULL,
  PRIMARY KEY (KKID)
);
CREATE TABLE Lieferant (
  LID INTEGER NOT NULL,
  Name VARCHAR(100) NOT NULL,
  PRIMARY KEY (LID)
);
CREATE TABLE Artikel (
  AID INTEGER NOT NULL,
  Bez VARCHAR(200) NOT NULL,
  PRIMARY KEY (AID)
);
CREATE TABLE Bestellung (
  BID INTEGER NOT NULL,
  BestellDatum DATE NOT NULL,
  KID INTEGER NOT NULL,
  PRIMARY KEY (BID)
);
CREATE TABLE Bestellposition (
  LfdNr INTEGER NOT NULL,
  BID INTEGER NOT NULL,
  Menge INTEGER NOT NULL,
  AID INTEGER NOT NULL,
  PRIMARY KEY (LfdNr, BID)
);
CREATE TABLE Verkaufkondition (
  fuer_KKID INTEGER NOT NULL,
  VK_ArtikelID INTEGER NOT NULL,
  Preis DECIMAL(9,2) NOT NULL,
  PRIMARY KEY (fuer_KKID, VK_ArtikelID)
);
CREATE TABLE Einkaufskondition (
  fuer_LieferantID INTEGER NOT NULL,
  EK_ArtikelID INTEGER NOT NULL,
  DauerInTagen INTEGER NOT NULL,
  Preis DECIMAL(9,2) NOT NULL,
  PRIMARY KEY (fuer_LieferantID, EK_ArtikelID)
);
ALTER TABLE Kunde
  ADD CONSTRAINT fk_hat_Kategorie FOREIGN KEY (KKID) REFERENCES Kundenkategorie (KKID);
ALTER TABLE Bestellung
  ADD CONSTRAINT fk_Bestellung_Kunde_assoc FOREIGN KEY (KID) REFERENCES Kunde (KID);
ALTER TABLE Bestellposition
  ADD CONSTRAINT fk_Bestellposition_Bestellung FOREIGN KEY (BID) REFERENCES Bestellung (BID);
ALTER TABLE Bestellposition
  ADD CONSTRAINT fk_Bestellposition_Artikel_assoc FOREIGN KEY (AID) REFERENCES Artikel (AID);
ALTER TABLE Verkaufkondition
  ADD CONSTRAINT fk_Verkaufkondition_fuer_KK FOREIGN KEY (fuer_KKID) REFERENCES Kundenkategorie (KKID);
ALTER TABLE Verkaufkondition
  ADD CONSTRAINT fk_Verkaufkondition_VK_Artikel FOREIGN KEY (VK_ArtikelID) REFERENCES Artikel (AID);
ALTER TABLE Einkaufskondition
  ADD CONSTRAINT fk_Einkaufskondition_fuer_Lieferant FOREIGN KEY (fuer_LieferantID) REFERENCES Lieferant (LID);
ALTER TABLE Einkaufskondition
  ADD CONSTRAINT fk_Einkaufskondition_EK_Artikel FOREIGN KEY (EK_ArtikelID) REFERENCES Artikel (AID);

Generalisierung

er_yaml = """
entities:
- entityname: Person
  key: PID
  attributes:
  - attributename: Name
    type: VARCHAR(100)

- entityname: Lehrperson
  attributes:
  - attributename: Steuernummer
    type: VARCHAR(20)

- entityname: StudentIn
  attributes:
  - attributename: MatrNr
    type: VARCHAR(10)

inheritances:
- superentity: Person
  subentities:
  - Lehrperson
  - StudentIn
"""
erman = ERSchemaMan.fromStr(er_yaml)
erman.display_mermaid_diagram(direction="TB", height="400px")
relman = RelSchemaMan.fromAST(erman.get_rel())
relman.display_mermaid_diagram(direction="BT", height="500px")
display_sql(relman.get_sql())



CREATE TABLE Person (
  PID INTEGER NOT NULL,
  Name VARCHAR(100) NOT NULL,
  PRIMARY KEY (PID)
);
CREATE TABLE Lehrperson (
  PID INTEGER NOT NULL,
  Steuernummer VARCHAR(20) NOT NULL,
  PRIMARY KEY (PID)
);
CREATE TABLE StudentIn (
  PID INTEGER NOT NULL,
  MatrNr VARCHAR(10) NOT NULL,
  PRIMARY KEY (PID)
);
ALTER TABLE Lehrperson
  ADD CONSTRAINT fk_Lehrperson_Person FOREIGN KEY (PID) REFERENCES Person (PID);
ALTER TABLE StudentIn
  ADD CONSTRAINT fk_StudentIn_Person FOREIGN KEY (PID) REFERENCES Person (PID);

Erzeugung von Oracle-Code

er_yaml = """
entities:
- entityname: Lehrperson
  key: LPID
  attributes:
  - attributename: Name
    type: VARCHAR(100)
  - attributename: EMail
    type: VARCHAR(100)
    nullable: True

- entityname: Gebaeude
  key: GID
  attributes:
  - attributename: Bez
    type: VARCHAR(50)

relationships:
- relationshipname: hat_buero_in
  entities:
  - targetentity: Lehrperson
    cardinality: OPTIONAL_MANY
  - targetentity: Gebaeude
    cardinality: OPTIONAL_ONE
"""
erman = ERSchemaMan.fromStr(er_yaml)
# erman.display_mermaid_diagram(direction="LR", height="200px")
relman = RelSchemaMan.fromAST(erman.get_rel())
# relman.display_mermaid_diagram(direction="LR", height="300px")
sql = relman.get_sql()
osql = transpile_postgres_sql(sql, target_dialect="oracle")
display_sql(osql)

CREATE TABLE Lehrperson (LPID NUMBER NOT NULL, Name VARCHAR2(100) NOT NULL, EMail VARCHAR2(100), GID NUMBER, PRIMARY KEY (LPID));
CREATE TABLE Gebaeude (GID NUMBER NOT NULL, Bez VARCHAR2(50) NOT NULL, PRIMARY KEY (GID));
ALTER TABLE Lehrperson ADD CONSTRAINT fk_hat_buero_in FOREIGN KEY (GID) REFERENCES Gebaeude (GID)

Erzeugung von DuckDB-Code

DuckDB unterstützt kein ALTER TABLE für Fremdschlüssel. Daher werden Fremdschlüssel in der CREATE TABLE-Anweisung definiert. Das erfolgt durch durch den Parameter fk_external=False bei der SQL-Code-Erzeugung

er_yaml = """
entities:
- entityname: Lehrperson
  key: LPID
  attributes:
  - attributename: Name
    type: VARCHAR(100)
  - attributename: EMail
    type: VARCHAR(100)
    nullable: True

- entityname: Gebaeude
  key: GID
  attributes:
  - attributename: Bez
    type: VARCHAR(50)

relationships:
- relationshipname: hat_buero_in
  entities:
  - targetentity: Lehrperson
    cardinality: OPTIONAL_MANY
  - targetentity: Gebaeude
    cardinality: OPTIONAL_ONE
"""
erman = ERSchemaMan.fromStr(er_yaml)
# erman.display_mermaid_diagram(direction="LR", height="200px")
relman = RelSchemaMan.fromAST(erman.get_rel())
# relman.display_mermaid_diagram(direction="LR", height="300px")
display_sql(relman.get_sql(fk_external=False))

CREATE TABLE Gebaeude (
  GID INTEGER NOT NULL,
  Bez VARCHAR(50) NOT NULL,
  PRIMARY KEY (GID)
);
CREATE TABLE Lehrperson (
  LPID INTEGER NOT NULL,
  Name VARCHAR(100) NOT NULL,
  EMail VARCHAR(100),
  GID INTEGER,
  PRIMARY KEY (LPID),
  CONSTRAINT fk_hat_buero_in FOREIGN KEY (GID) REFERENCES Gebaeude (GID)
);

Verwendung von DuckDB

  • Erzeugung einer in-memory DuckDB-Instanz
  • Ausführung von SQL-Code zur Erstellung der Tabellen
  • Ausführung von SQL-Code zum Einfügen von Daten
  • Ausführen und Anzeigen der Ergebnisse einer Abfrage
dbman = DuckDbMan.fromMem()
  
sql = """
CREATE TABLE Gebaeude (
  GID INTEGER NOT NULL,
  Bez VARCHAR(50) NOT NULL,
  PRIMARY KEY (GID)
);
CREATE TABLE Lehrperson (
  LPID INTEGER NOT NULL,
  Name VARCHAR(100) NOT NULL,
  EMail VARCHAR(100),
  GID INTEGER,
  PRIMARY KEY (LPID),
  CONSTRAINT fk_hat_buero_in FOREIGN KEY (GID) REFERENCES Gebaeude (GID)
);
"""
dbman.execute(sql)

sql = """
insert into Gebaeude values (1, 'C');
insert into Lehrperson values (1, 'Claßen', 'ingo.classen@htw-berlin.de', 1);
insert into Lehrperson values (2, 'Kempa', 'martin.kempa@htw-berlin.de', 1);
"""
dbman.execute(sql)

sql = """
select g.Bez as Gebaeude, lp.Name as Lehrperson, lp.EMail
from Gebaeude g
     join Lehrperson lp on g.GID = lp.GID
"""
dbman.print(sql)
┌──────────┬────────────┬────────────────────────────┐
│ Gebaeude │ Lehrperson │           EMail            │
│ varchar  │  varchar   │          varchar           │
├──────────┼────────────┼────────────────────────────┤
│ C        │ Claßen     │ ingo.classen@htw-berlin.de │
│ C        │ Kempa      │ martin.kempa@htw-berlin.de │
└──────────┴────────────┴────────────────────────────┘

Datengenerierung mit der KI

  • Erstellung eines Relationship-Managers
    • Ausgangspunkt ist ein ER-Modell
    • Daraus Erstellung eines ER-Managers (erman)
    • Daraus Erstellung des Relationship-Managers (relman)
  • Erstellung einer DataGenConversation
  • Setzen des Datenbankschemas
  • Einfügen einer Datengenerierungs-Nachricht
    • Tabelle Modulart wird ausgeschlossen
    • Die Insert-Statements für die Tabelle werden bereits über die Valuelist generiert
  • Erstellen des Prompts für die KI der Wahl (ChatGPT, Claude, usw.)
er_yaml = """
entities:
- entityname: Modul
  key: MID
  attributes:
  - attributename: Bez
    type: VARCHAR(50)
valuelists:
- valuelistname: Modulart
  values:
  - Pflicht
  - Wahlpflicht
  - Wahl
  many_to_one_from_entities:
  - sourceentity: Modul
"""
erman = ERSchemaMan.fromStr(er_yaml)
relman = RelSchemaMan.fromAST(erman.get_rel())

datagen_conv = DataGenConversation()
datagen_conv.set_database_schema(relman.get_yaml())
datagen_conv.insert_datagen_message(
    no_of_records_per_table=5, 
    exclude_tables=["Modulart"]
    )

print(datagen_conv.gen_prompt())

Der Prompt für die KI:

You are a helpful assistant for generating synthetic data for SQL tables.
You will be given a YAML description of the tables and their relationships.
Your task is to generate SQL insert statements to create synthetic data 
for the tables, while respecting the relationships and constraints described in the YAML.

The following tables are given:
```yaml
tables:
- tablename: Modul
  columns:
  - columnname: MID
    type: INTEGER
  - columnname: Bez
    type: VARCHAR(50)
  - columnname: ModulartID
    type: INTEGER
  primary_key:
  - MID
  foreign_keys:
  -
    fkname: fk_Modul_Modulart
    sourcecolumns:
    - ModulartID
    targettable: Modulart
    targetcolumns:
    - ID
- tablename: Modulart
  columns:
  - columnname: ID
    type: INTEGER
  - columnname: Description
    type: VARCHAR(100)
  - columnname: IsValid
    type: INTEGER
  - columnname: SortOrder
    type: INTEGER
  primary_key:
  - ID
datalists:
- tablename: Modulart
  values:
  - Pflicht
  - Wahlpflicht
  - Wahl
```
Future request will be based on this schema.

Create at least 5 insert statements for each table.
Don't repeat already given data.

Don'create insert statements for the following tables: 'Modulart'.

Kopieren des Prompts in die KI (hier ChatGPT).
Screenshot:

  • Rechts oben ist des Ende des Prompts zu sehen
  • Darunter die generierten SQL-Insert-Statements
  • Achtung: Die tatsächlichen generierten Daten können bei jedem Durchlauf anders sein

  • DuckDB-Instanz erstellen
  • Mit Schema und Valuelist befüllen
  • Modulartdaten anzeigen
dbman = DuckDbMan.fromMem()
dbman.execute(relman.get_sql(fk_external=False))
dbman.print("select * from Modulart")
┌───────┬─────────────┬─────────┬───────────┐
│  ID   │ Description │ IsValid │ SortOrder │
│ int32 │   varchar   │  int32  │   int32   │
├───────┼─────────────┼─────────┼───────────┤
│     1 │ Pflicht     │       1 │         1 │
│     2 │ Wahlpflicht │       1 │         2 │
│     3 │ Wahl        │       1 │         3 │
└───────┴─────────────┴─────────┴───────────┘

  • Kopieren der generierten SQL-Insert-Statements aus der KI
  • Ausführen in DuckDB
  • Ausführen einer SQL-Abfrage und Anzeige des Ergebnisses
sql = """
-- Insert statements for table: Modul
-- Assumption:
-- Modulart IDs already exist in table Modulart
-- 1 = Pflicht
-- 2 = Wahlpflicht
-- 3 = Wahl

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (101, 'Datenbanksysteme', 1);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (102, 'Software Engineering', 1);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (103, 'Künstliche Intelligenz', 2);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (104, 'Webentwicklung', 2);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (105, 'IT-Sicherheit', 3);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (106, 'Cloud Computing', 3);
"""
dbman.execute(sql)

sql = """
select m.bez as Modul, ma.description as Modulart
from Modul m
join Modulart ma on m.ModulartID = ma.ID
"""
dbman.print(sql)
┌────────────────────────┬─────────────┐
│         Modul          │  Modulart   │
│        varchar         │   varchar   │
├────────────────────────┼─────────────┤
│ Datenbanksysteme       │ Pflicht     │
│ Software Engineering   │ Pflicht     │
│ Künstliche Intelligenz │ Wahlpflicht │
│ Webentwicklung         │ Wahlpflicht │
│ IT-Sicherheit          │ Wahl        │
│ Cloud Computing        │ Wahl        │
└────────────────────────┴─────────────┘

ER-Modell-Generierung mit der KI

  • Anlegen einer ERDesignConversation
  • Einfügen einer Design-Message
  • Erstellen des Prompts für die KI der Wahl (ChatGPT, Claude, usw.)
er_conv = ERDesignConversation()
  
design_msg = """
Entwirf ein einfaches ER-Diagramm für ein Krankenhaussystem. 
Es soll Informationen über Patienten, Ärzte und Behandlungen speichern. 
Jede Behandlung hat ein Datum und eine Beschreibung.
"""
er_conv.insert_design_message(design_msg)
print(er_conv.gen_prompt())

Der Prompt wird hier nicht gezeigt, da er sehr lang ist.


  • Kopieren des Prompts in die KI
  • Den Output der KI (ER-Diagramm im YAML-Format) kopieren
  • Den YAML-Output in den Code einfügen
  • Er-Schema-Manager aus dem YAML erstellen
  • ER-Diagramm anzeigen lassen
er_yaml = """
entities:
- entityname: Patient
  key: PatientID
  attributes:
  - attributename: Vorname
    type: TEXT
  - attributename: Nachname
    type: TEXT
  - attributename: Geburtsdatum
    type: DATE
    nullable: True

- entityname: Arzt
  key: ArztID
  attributes:
  - attributename: Vorname
    type: TEXT
  - attributename: Nachname
    type: TEXT
  - attributename: Fachgebiet
    type: TEXT
    nullable: True

associative_entities:
- associationname: Behandlung
  identification:
    localkey: BehandlungID
  associations:
  - targetentity: Patient
    role: Patient
    cardinality: ONE
  - targetentity: Arzt
    role: Arzt
    cardinality: ONE
  attributes:
  - attributename: Behandlungsdatum
    type: DATE
  - attributename: Beschreibung
    type: TEXT
"""
erman = ERSchemaMan.fromStr(er_yaml)
erman.display_mermaid_diagram(direction="TB", height="450")
  • Achtung: Das tatsächlich generierte Modell kann bei jedem Durchlauf anders sein
  • Der YAML-Output der KI ist möglicherweise nicht perfekt
  • Er kann manuell weiterbearbeitet werden

Requirements-Generierung mit der KI

  • Anlegen einer ERRequirementsConversation
  • Einfügen einer Requirements-Message
  • Erstellen des Prompts für die KI der Wahl (ChatGPT, Claude, usw.)
er_conv = ERRequirementsConversation()
  
req_msg = """
Beschreibe die Anforderungen für ein Krankhaussystem.
"""
er_conv.insert_requirements_message(req_msg)
print(er_conv.gen_prompt())

Der Prompt wird hier nicht gezeigt, da er sehr lang ist.


  • Kopieren des Prompts in die KI
  • Den Output der KI (Requirements-Dokument im Markdown-Format) kopieren
  • Den Markdown-Output in den Code einfügen
  • Requirements-Dokument anzeigen lassen
req_md = """
Hier den Markdown-Output der KI einfügen
"""
display_md(req_md)

Der Output wird hier nicht abgebildet, da er sehr lang ist.
Das Markdown-Dokument dann in die ERDesignConversation einfügen.

SQL-Generierung mit der KI

  • Erstellung eines Relationship-Managers
    • Ausgangspunkt ist ein ER-Modell
    • Daraus Erstellung eines ER-Managers (erman)
    • Daraus Erstellung des Relationship-Managers (relman)
  • Anlegen einer DuckDB-Instanz
  • Verwendung des SQL-Codes des Relationship-Managers
    • relman.get_sql(fk_external=False)
    • Das führt zum Erstellen der Tabellen
    • Und zum Einfügen von Valuelist-Daten
er_yaml = """
entities:
- entityname: Modul
  key: MID
  attributes:
  - attributename: Bez
    type: VARCHAR(50)
valuelists:
- valuelistname: Modulart
  values:
  - Pflicht
  - Wahlpflicht
  - Wahl
  many_to_one_from_entities:
  - sourceentity: Modul
"""
erman = ERSchemaMan.fromStr(er_yaml)
relman = RelSchemaMan.fromAST(erman.get_rel())
dbman = DuckDbMan.fromMem()
dbman.execute(relman.get_sql(fk_external=False))
dbman.print("select * from Modulart")
┌───────┬─────────────┬─────────┬───────────┐
│  ID   │ Description │ IsValid │ SortOrder │
│ int32 │   varchar   │  int32  │   int32   │
├───────┼─────────────┼─────────┼───────────┤
│     1 │ Pflicht     │       1 │         1 │
│     2 │ Wahlpflicht │       1 │         2 │
│     3 │ Wahl        │       1 │         3 │
└───────┴─────────────┴─────────┴───────────┘

  • Einfügen von Daten in die Tabelle Modul
sql = """
INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (101, 'Datenbanksysteme', 1);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (102, 'Software Engineering', 1);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (103, 'Künstliche Intelligenz', 2);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (104, 'Webentwicklung', 2);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (105, 'IT-Sicherheit', 3);

INSERT INTO Modul (MID, Bez, ModulartID)
VALUES (106, 'Cloud Computing', 3);
"""
dbman.execute(sql)
dbman.print("select * from Modul")
┌───────┬────────────────────────┬────────────┐
│  MID  │          Bez           │ ModulartID │
│ int32 │        varchar         │   int32    │
├───────┼────────────────────────┼────────────┤
│   101 │ Datenbanksysteme       │          1 │
│   102 │ Software Engineering   │          1 │
│   103 │ Künstliche Intelligenz │          2 │
│   104 │ Webentwicklung         │          2 │
│   105 │ IT-Sicherheit          │          3 │
│   106 │ Cloud Computing        │          3 │
└───────┴────────────────────────┴────────────┘

  • Anlegen einer SQLGenConversation
  • Datenbank-Schema festlegen
  • Frage stellen
  • Prompt generieren
sql_conv = SQLGenConversation()
sql_conv.set_database_schema(relman.get_yaml())
sql_conv.insert_question_message("Anzahl Module pro Modulart")
print(sql_conv.gen_prompt())
You are an expert SQL query generator. 
Convert natural language questions into valid SQL queries. 

The following database schema is given:
tables:
- tablename: Modul
  columns:
  - columnname: MID
    type: INTEGER
  - columnname: Bez
    type: VARCHAR(50)
  - columnname: ModulartID
    type: INTEGER
  primary_key:
  - MID
  foreign_keys:
  -
    fkname: fk_Modul_Modulart
    sourcecolumns:
    - ModulartID
    targettable: Modulart
    targetcolumns:
    - ID
- tablename: Modulart
  columns:
  - columnname: ID
    type: INTEGER
  - columnname: Description
    type: VARCHAR(100)
  - columnname: IsValid
    type: INTEGER
  - columnname: SortOrder
    type: INTEGER
  primary_key:
  - ID
datalists:
- tablename: Modulart
  values:
  - Pflicht
  - Wahlpflicht
  - Wahl

Future request will be based on this schema.
The user's question is:
Anzahl Module pro Modulart
Turn this question into a valid postgres SQL query based on the given database schema.
Return the SQL query only, without any explanation or additional text.

  • Prompt in die KI einfügen
  • Output der KI (SQL-Anweisung) in den Python-Code kopieren
  • In der DuckDB-Instanz ausführen
sql = """
SELECT 
    ma.Description AS modulart,
    COUNT(m.MID) AS anzahl_module
FROM Modul m
JOIN Modulart ma ON m.ModulartID = ma.ID
GROUP BY ma.Description
ORDER BY anzahl_module DESC;
"""
dbman.print(sql)
┌─────────────┬───────────────┐
│  modulart   │ anzahl_module │
│   varchar   │     int64     │
├─────────────┼───────────────┤
│ Wahl        │             2 │
│ Wahlpflicht │             2 │
│ Pflicht     │             2 │
└─────────────┴───────────────┘