"""PERS-001/002: Person fachlich getrennt von Benutzer (Login), Backfill bestehender Benutzer. Revision ID: 0034_person Revises: 0033_wartungsauftrag_teil Create Date: 2026-09-08 """ from typing import Sequence, Union from alembic import op revision: str = "0034_person" down_revision: Union[str, None] = "0033_wartungsauftrag_teil" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: op.execute( """ CREATE TABLE person ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, geburtsdatum DATE, kontakt TEXT ) """ ) op.execute("ALTER TABLE benutzer ADD COLUMN person_id INTEGER REFERENCES person(id)") op.execute("CREATE INDEX ix_benutzer_person_id ON benutzer (person_id)") # Backfill: jeder bestehende Benutzer bekommt eine EIGENE Person mit gleichem # Namen (1:1 per Zeilennummer statt Namensvergleich, sonst würden Benutzer # mit identischem Namen fälschlich derselben Person zugeordnet). op.execute( """ INSERT INTO person (name) SELECT name FROM benutzer ORDER BY id """ ) op.execute( """ WITH benutzer_rang AS ( SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS rang FROM benutzer ), person_rang AS ( SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS rang FROM person ) UPDATE benutzer SET person_id = person_rang.id FROM benutzer_rang JOIN person_rang ON person_rang.rang = benutzer_rang.rang WHERE benutzer.id = benutzer_rang.id """ ) def downgrade() -> None: op.execute("ALTER TABLE benutzer DROP COLUMN person_id") op.execute("DROP TABLE person")