fix(crm): DB-Migrationen idempotent machen für Neuinstallationen

Bei Neuinstallation erzeugt create_all bereits das gesamte Schema,
so dass nachfolgende ALTER-Table-Migrationen fehlschlagen ("duplicate
column name"). V01_04 prüft nun die Spalten-Existenz per PRAGMA
table_info. checkupdates läuft wieder sequentiell ohne Überspringen.
Konvention in AGENTS.md dokumentiert.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
gg committed 2026-09-15 17:36:52 +02:00
1 parent efef212544
commit 44c411e5d7
2 files changed
+22 -3

No files matched your search

+17 -3
View File
@@ -83,10 +83,19 @@ def _db_V01_04():
Fügt die Spalte 'position' zur Tabelle 'kontaktadressen' hinzu.
Bei bestehenden Datenbanken, die mit Version 01.03 initialisiert wurden,
fehlt diese Spalte, da das Feld erst nachträglich ergänzt wurde.
Idempotent: Bei Neuinstallation hat create_all die Spalte bereits
angelegt — in diesem Fall wird das ALTER TABLE übersprungen.
"""
from sqlalchemy import text
session.execute(text("ALTER TABLE kontaktadressen ADD COLUMN position VARCHAR(200)"))
# Prüfen, ob die Spalte bereits existiert (Neuinstallation via create_all)
result = session.execute(text("PRAGMA table_info(kontaktadressen)"))
spalten = {row[1] for row in result}
if 'position' not in spalten:
session.execute(text(
"ALTER TABLE kontaktadressen ADD COLUMN position VARCHAR(200)"
))
_updatesysteminfo('01.04')
session.commit()
@@ -217,7 +226,14 @@ def checkupdates():
Ermittelt die aktuelle DB-Version aus der Systeminfo-Tabelle und führt alle
_db_Vxx_xx-Funktionen aus, deren Versionsnummer größer ist. Ist die
Datenbank noch leer (Tabelle fehlt), wird die Ersteinrichtung ausgeführt.
Bei einer Neuinstallation erzeugt _db_V01_00 über create_all bereits alle
Tabellen mit dem aktuellen Schema (inklusive aller später ergänzten Spalten,
Tabellen und Indizes). Die inkrementellen Migrationen laufen trotzdem
sequentiell nach — jede einzelne muss idempotent sein, damit sie auf der
frisch erzeugten DB fehlerfrei durchläuft (siehe Konvention in AGENTS.md).
"""
versionen = sorted(filter(lambda f: f.startswith("_db_V"), globals()))
curr_dbversion = '_db_V01_00'
try:
systeminfo: CrmSysteminfo = CrmSysteminfo.query.get(1)
@@ -225,8 +241,6 @@ def checkupdates():
except (OperationalError, AttributeError):
_db_V01_00()
versionen = sorted(filter(lambda f: f.startswith("_db_V"), globals()))
for v in versionen:
if v > curr_dbversion:
globals()[v]()