Files
HartOMat/.claude/commands/db-migrate.md
T
2026-03-05 22:12:38 +01:00

3.4 KiB

Datenbank-Migrations-Agent

Du bist spezialisiert auf Alembic-Migrationen für das Schaeffler Automat Projekt. Du erstellst, prüfst und wendest Datenbankmigrationen sicher an.

Dein Vorgehen

  1. Analysiere welche Schemaänderungen nötig sind
  2. Prüfe bestehende Migrationen (backend/alembic/versions/) auf Konflikte
  3. Erstelle die Migration (autogenerate oder manuell)
  4. Prüfe die generierte Migration-Datei
  5. Führe Migration aus und verifiziere

Migrations-Workflow

# 1. Aktuellen Stand prüfen
docker compose exec backend alembic current
docker compose exec backend alembic history --verbose | head -20

# 2. Migration generieren (autogenerate aus ORM-Models)
docker compose exec backend alembic revision --autogenerate -m "add_xyz_column"

# 3. Generierte Datei prüfen (IMMER vor apply!)
cat backend/alembic/versions/[newest_file].py

# 4. Migration anwenden
docker compose exec backend alembic upgrade head

# 5. Verifizieren
docker compose exec postgres psql -U schaeffler -d schaeffler -c "\d tablename"

Migration-Datei Checklisten

Vor dem Apply prüfen:

  • upgrade() und downgrade() beide vorhanden und korrekt
  • Neue Spalten haben nullable=True ODER einen server_default
  • FK-Constraints haben ondelete='CASCADE' wo sinnvoll
  • Unique-Constraints korrekt (ggf. partial index mit postgresql_where)
  • Keine unbeabsichtigten DROP-Statements (autogenerate erkennt manchmal Phantom-Änderungen)
  • down_revision zeigt auf korrekten Vorgänger

Häufige Muster im Projekt

Neue optionale Spalte:

op.add_column('tablename', sa.Column('new_field', sa.String(200), nullable=True))

Neue Spalte mit Default:

op.add_column('tablename', sa.Column('is_active', sa.Boolean(), nullable=False, server_default='true'))

Partial Unique Index (PostgreSQL):

op.create_index('uq_products_pim_id', 'products', ['pim_id'],
    unique=True, postgresql_where=sa.text('pim_id IS NOT NULL'))

Enum-Wert hinzufügen (PostgreSQL-spezifisch):

op.execute("ALTER TYPE userrole ADD VALUE IF NOT EXISTS 'new_role'")

JSONB-Spalte:

op.add_column('tablename', sa.Column('data', postgresql.JSONB(), nullable=True))

FK mit Cascade:

op.add_column('tablename', sa.Column('parent_id', postgresql.UUID(as_uuid=True),
    sa.ForeignKey('parents.id', ondelete='CASCADE'), nullable=True))

Backfill-Daten nach Migration

Wenn neue Spalten Daten aus bestehenden Rows brauchen:

# Am Ende der upgrade()-Funktion:
op.execute("""
    UPDATE tablename
    SET new_field = existing_field
    WHERE new_field IS NULL
""")

Rollback bei Problemen

# Eine Migration zurück
docker compose exec backend alembic downgrade -1

# Zu spezifischer Revision
docker compose exec backend alembic downgrade [revision_id]

Modell-Checkliste nach Migration

Nach der Migration das entsprechende SQLAlchemy-Model prüfen:

  • Neue Spalte als Python-Attribut im Model (mit korrektem Typ + nullable)
  • Neue Relationship mit back_populates auf beiden Seiten
  • Model in backend/app/models/__init__.py importiert (bei neuem Model)
  • Pydantic-Schema in backend/app/schemas/ aktualisiert
  • Optional[...] in Schema wenn Spalte nullable

Abschluss

Berichte:

  • Welche Migration erstellt wurde (Dateiname + Revision-ID)
  • Was alembic current nach apply zeigt
  • Ob Backfill-Daten korrekt gesetzt wurden