Mehrere Dashboards und dieselbe Karte mehrfach
Zwei Grenzen sassen tief im Datenmodell. Erstens war "i" im gespeicherten Layout zugleich die Kartenart; da react-grid-layout eindeutige Kennungen verlangt, ging jede Art genau einmal - zwei Artikel gleichzeitig beobachten war damit unmoeglich. Zweitens war dashboard_layouts.user_id unique, also genau ein Dashboard je Benutzer. Jetzt ist "i" die Kennung dieser einen Karte und "type" ihre Art, dazu kommt "props" fuer das, was nur diese Karte angeht (etwa welcher Artikel). Aeltere Anordnungen haben kein "type"; fuer sie gilt die alte Kennung als Art, sodass gespeicherte Startseiten unveraendert weiterlaufen. Die Tabelle bekommt Name und Reihenfolge, das unique faellt. Sein Name haengt davon ab, wie die Tabelle entstanden ist, deshalb wird er in pg_constraint nachgeschlagen statt geraten. Eine Feinheit beim Anlegen: Wer noch auf der Admin-Vorgabe sitzt und sein erstes eigenes Dashboard anlegt, wuerde die Vorgabe schlagartig verlieren - sobald eigene Zeilen da sind, zaehlen nur noch die. Deshalb wird sie vorher uebernommen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -61,10 +61,26 @@ def _ensure_schema() -> None:
|
||||
"NOT NULL DEFAULT 'day'",
|
||||
"ALTER TABLE products ADD COLUMN IF NOT EXISTS category_id INTEGER "
|
||||
"REFERENCES categories(id) ON DELETE SET NULL",
|
||||
# Mehrere Dashboards je Benutzer: Name und Reihenfolge kommen dazu.
|
||||
"ALTER TABLE dashboard_layouts ADD COLUMN IF NOT EXISTS name VARCHAR(80) "
|
||||
"NOT NULL DEFAULT 'Übersicht'",
|
||||
"ALTER TABLE dashboard_layouts ADD COLUMN IF NOT EXISTS position INTEGER "
|
||||
"NOT NULL DEFAULT 0",
|
||||
]
|
||||
with engine.begin() as conn:
|
||||
for stmt in stmts:
|
||||
conn.execute(text(stmt))
|
||||
# Solange user_id eindeutig war, ging genau ein Dashboard je Benutzer.
|
||||
# Der Name der Beschraenkung haengt davon ab, wie die Tabelle entstanden
|
||||
# ist, deshalb wird er nachgeschlagen statt geraten.
|
||||
namen = conn.execute(
|
||||
text(
|
||||
"SELECT conname FROM pg_constraint "
|
||||
"WHERE conrelid = 'dashboard_layouts'::regclass AND contype = 'u'"
|
||||
)
|
||||
).scalars().all()
|
||||
for name in namen:
|
||||
conn.execute(text(f'ALTER TABLE dashboard_layouts DROP CONSTRAINT "{name}"'))
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
|
||||
Reference in New Issue
Block a user