Added docs on FK and PK (#504)

This commit is contained in:
Philipp Horstenkamp 2024-01-03 18:30:35 +01:00 committed by GitHub
parent 797dd165a8
commit 6e0247c58c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 13 deletions

View File

@ -1,13 +1,15 @@
### Database Generator (Philipp Horstenkamp)
Zur Definition eines Relationalen Datenbankschemas und zur Härtung gegen SQL-Injections wurde SQLAlchemy als SQL-Interface / Driver / Abstraction layer genutzt.
SQLAlchemy sorgt dabei für ein Dialekt unabhängiges Interface, um unabhängig von der verwendeten Datenbank zu sein.
Zur Definition eines relationalen Datenbankschemas und zur Absicherung gegen SQL-Injections nutzen wir SQLAlchemy.
Es dient als SQL-Interface, Treiber und Abstraktionsschicht.
SQLAlchemy bietet ein dialektunabhängiges Interface, um datenbankunabhängig zu arbeiten.
Auch wenn es seit einiger Zeit SQLAlchemy2 gibt haben wir uns entschieden Version 1.4 zu nutzen da es zur Version 2 nur wenig Dokumentation, externe Dokumentation und Beispiele gab.
SQLAlchemy ist ein sehr mächtiges und beliebtes Werkzeug, leider ist die Projektdokumentation sehr undurchsichtig.
Da aber SQLAlchemy1.4 zurzeit noch gewartet wird, ist dies für dieses Projekt kein Problem.
Obwohl SQLAlchemy2 existiert, entschieden wir uns für Version 1.4.
Der Grund ist die begrenzte Dokumentation und weniger externe Ressourcen für Version 2.
SQLAlchemy ist ein mächtiges und beliebtes Tool, aber seine Projektdokumentation ist oft undurchsichtig.
Da SQLAlchemy1.4 jedoch noch unterstützt wird, stellt dies für unser Projekt kein Problem dar.
Hier ein kurzes Beispiel einer SQL-Definition via SQLAlchemy.
Im Folgenden ein kurzes Beispiel einer SQL-Definition mittels SQLAlchemy.
```python
import sqlalchemy as sa
@ -47,7 +49,15 @@ class Company(Base):
founding_date = sa.Column(sa.Date, nullable=True)
```
### TODO PK - FK Definition
Primärschlüssel und Fremdschlüssel (*PK*/*FK*) werden durch SQL-Alchemy-Klassen definiert.
Wir setzen `primary_key=True` für jede PK-Spalte, was auch über `__table_args__` möglich ist.
`__table_args__` umfasst alle Eigenschaften, die üblicherweise durch Tabelleneinstellungen definiert werden.
In unserem Fall beinhalten diese meist Constraints zur Datenvalidierung.
Fremdschlüssel definieren wir mit dem zusätzlichen Argument `sa.ForeignKey("district_court.id")`.
Dies zeigt an, dass eine Spalte einen FK zu einer anderen Spalte in einer anderen Tabelle darstellt.
In unserem Beispiel ist es die `id`-Spalte der Tabelle `district_court`.
Da wir in unserer Softwarearchitektur fast ausschließlich Daten einfügen, verzichten wir auf die Definition von `on_delete` und `on_update`.
Die einzige Tabelle, die Änderungen unterliegt, verwendet keine FKs.
Natürlich ist es manchmal sinnvoll SQL-Tabellen dynamischer und mit wenig Code-Duplication zu generieren.
Eine Möglichkeit dazu ist die folgende Definition in der die Union einiger Teildefinitionen als Dictionary.
@ -71,9 +81,9 @@ AnnualFinanceStatement = type(
)
```
Das Anlegen der Klassen alleine reicht nicht aus, um diese in einer SQL-Datenbank anzulegen.
Diese müssen über das `Base`-Objekt wie folgt Initialisiert werden.
Dabei werden nur fehlende Tabellen initialisiert.
Das bloße Anlegen der Klassen genügt nicht, um sie in einer SQL-Datenbank zu erstellen.
Sie müssen über das `Base`-Objekt wie folgt initialisiert werden:
Nur fehlende Tabellen werden dabei initialisiert.
```python
Base.metadata.create_all(db.bind)
@ -90,5 +100,5 @@ Das resultierende SQL-Schema sieht dann wie folgt aus:
:page-index: 1
```
Es gibt Schema verändernde, versionierende Erweiterungen für `SQLAlchemy`, wie `Alembic` oder `SQLAlchemy-mirgrate`.
Durch ein Softwaredesign welche die Produktivtabellen aber regelmäßig reinitialisiert wird dies unnötig.
Es existieren schemaändernde, versionierende Erweiterungen für `SQLAlchemy`, wie `Alembic` oder `SQLAlchemy-migrate`.
Unser Softwaredesign, das die Produktivtabellen regelmäßig reinitialisiert, macht diese jedoch überflüssig.

View File

@ -3,9 +3,12 @@ Halte dich inhaltlich an die Vorgaben.
Korrigiere aber bitte, Grammatik, Zeichensetzung und Stil.
Bitte kürze / teile die Sätze wenn möglich.
```markdown
```
Bitte gib mir die überarbeitete version in Markdown (md) aus.
Dieses sollte in einem md codeblock angezeigt werden.
Bitte fange für jeden Satz eine neue Zeile an.
Sollten Fragen offen bleiben schreibe mir bitte einen kurzen Verweise auf den md block.
Sollten Fragen offen bleiben schreibe mir bitte einen kurzen Verweis nach md Code-Block.