Skip to content

Troubleshooting Migrations

Häufige Probleme und Lösungen bei Doctrine-Migrationen.

Migration erstellen

"No changes detected"

Problem:

bash
php bin/console doctrine:migrations:diff
# No changes detected

Ursachen & Lösungen:

  1. Entity nicht gemapped

    bash
    # Mapping-Info prüfen
    php bin/console doctrine:mapping:info
    
    # Sollte alle Entities zeigen
    # Wenn nicht: doctrine.yaml prüfen
  2. Cache-Problem

    bash
    php bin/console cache:clear
    php bin/console doctrine:migrations:diff
  3. Schema bereits aktuell

    bash
    # Diff manuell anzeigen
    php bin/console doctrine:schema:update --dump-sql
    
    # Wenn leer → alles aktuell
  4. Falsches Environment

    bash
    # Richtiges Environment nutzen
    php bin/console doctrine:migrations:diff --env=dev

Migration landet in falschem Ordner

Problem:

  • Migration wird in 1_infrastructure/ erstellt, sollte aber in 5_domain/

Ursache:

  • Doctrine wählt automatisch ersten Namespace aus doctrine_migrations.yaml

Lösung:

Option 1: Migration manuell verschieben

bash
# Erstellen
php bin/console doctrine:migrations:diff

# Verschieben
mv migrations/1_infrastructure/Version20250124... migrations/5_domain/

# Namespace in Datei ändern
# namespace DoctrineMigrations\Infrastructure;  →
# namespace DoctrineMigrations\Domain;

Option 2: Temporary doctrine_migrations.yaml

yaml
# Nur gewünschten Namespace
doctrine_migrations:
    migrations_paths:
        'DoctrineMigrations\Domain': '%kernel.project_dir%/migrations/5_domain'

Danach Migration erstellen und Config zurücksetzen.

Migration ausführen

"Migration was executed but did not result in any SQL statements"

Problem:

bash
php bin/console doctrine:migrations:migrate
# Migration ... was executed but did not result in any SQL statements.

Ursache:

  • up() Methode leer oder nur Kommentare

Lösung:

php
public function up(Schema $schema): void
{
    // SQL hinzufügen
    $this->addSql('CREATE TABLE ...');
}

"Migration ... already executed"

Problem:

bash
Migration ... has already been executed.

Ursache:

  • Eintrag in doctrine_migration_versions Tabelle vorhanden

Lösungen:

Option 1: Version-Flag entfernen

sql
-- Als postgres User
psql -U appiyonadmin -d symfony

-- Prüfen
SELECT * FROM doctrine_migration_versions;

-- Version entfernen
DELETE FROM doctrine_migration_versions
WHERE version = 'DoctrineMigrations\\Infrastructure\\Version0001';

Option 2: Migration überspringen

bash
php bin/console doctrine:migrations:version DoctrineMigrations\\Infrastructure\\Version0001 --add --no-interaction

"Table already exists"

Problem:

bash
SQLSTATE[42P07]: Duplicate table: 7 ERROR: relation "admins" already exists

Ursachen & Lösungen:

  1. Tabelle wurde manuell erstellt

    sql
    -- Tabelle löschen
    DROP TABLE admins CASCADE;
    
    -- Migration erneut ausführen
    php bin/console doctrine:migrations:migrate
  2. Migration teilweise ausgeführt

    bash
    # Status prüfen
    php bin/console doctrine:migrations:status
    
    # Datenbank komplett neu aufsetzen
    php bin/console doctrine:database:drop --force
    php bin/console doctrine:database:create
    php bin/console doctrine:migrations:migrate
  3. Migration wurde bereits executed, aber Flag fehlt

    sql
    -- Version als executed markieren
    INSERT INTO doctrine_migration_versions (version, executed_at, execution_time)
    VALUES ('DoctrineMigrations\\Infrastructure\\Version0001', NOW(), 1);

"Syntax error in SQL"

Problem:

bash
SQLSTATE[42601]: Syntax error

Debugging:

bash
# SQL-Code ausgeben ohne Ausführung
php bin/console doctrine:migrations:migrate --dry-run

# In Migration-Datei prüfen
cat migrations/1_infrastructure/Version0001_admin.php

Häufige Fehler:

php
// Falsch: Fehlende Klammern
$this->addSql('CREATE TABLE admins
    id SERIAL PRIMARY KEY
');

// Richtig
$this->addSql('CREATE TABLE admins (
    id SERIAL PRIMARY KEY
)');

// Falsch: Vergessene Kommas
$this->addSql('CREATE TABLE admins (
    id INTEGER
    name VARCHAR(255)
)');

// Richtig
$this->addSql('CREATE TABLE admins (
    id INTEGER,
    name VARCHAR(255)
)');

Migration rückgängig machen

"Migration cannot be executed down"

Problem:

bash
php bin/console doctrine:migrations:migrate prev
# Migration ... cannot be executed down as it was not executed up.

Ursache:

  • Version nicht in doctrine_migration_versions

Lösung:

sql
-- Manuell als executed markieren
INSERT INTO doctrine_migration_versions (version, executed_at, execution_time)
VALUES ('DoctrineMigrations\\Infrastructure\\Version0001', NOW(), 1);

down() wirft Exception

Problem:

php
public function down(Schema $schema): void
{
    $this->throwIrreversibleMigrationException();
}

Lösung:

  • Entweder down() implementieren
  • Oder Datenbank neu aufsetzen:
bash
php bin/console doctrine:database:drop --force
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrate

Schema Out of Sync

"Database schema is not in sync"

Problem:

bash
php bin/console doctrine:schema:validate
[FAIL] The database schema is not in sync with the current mapping files.

Diagnose:

bash
# Unterschiede anzeigen
php bin/console doctrine:schema:update --dump-sql

Lösungen:

Option 1: Neue Migration (empfohlen)

bash
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate

Option 2: Direkt updaten (nur Dev!)

bash
php bin/console doctrine:schema:update --force

Option 3: Datenbank neu aufsetzen

bash
php bin/console doctrine:database:drop --force
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrate

Migration-Status Probleme

"Inconsistent migration status"

Problem:

bash
php bin/console doctrine:migrations:status
# Shows: 3 available, 5 executed

Ursache:

  • Migrations gelöscht, aber Flag noch in DB
  • Oder Migrations hinzugefügt, aber nicht executed

Lösung:

sql
-- Alle Versions anzeigen
SELECT * FROM doctrine_migration_versions ORDER BY version;

-- Falsche Versions löschen
DELETE FROM doctrine_migration_versions
WHERE version NOT IN (
    'DoctrineMigrations\\Infrastructure\\Version0001',
    'DoctrineMigrations\\Shared\\Version0001'
    -- Nur echte Migrations
);

doctrine_migration_versions Tabelle fehlt

Problem:

bash
SQLSTATE[42P01]: Undefined table: relation "doctrine_migration_versions" does not exist

Lösung:

bash
# Erste Migration ausführen, erstellt automatisch Tabelle
php bin/console doctrine:migrations:migrate --no-interaction

# Oder manuell erstellen
php bin/console doctrine:migrations:version --add --all --no-interaction

Namespace-Probleme

"Class ... not found"

Problem:

bash
Class "DoctrineMigrations\Infrastructure\Version0001" not found

Ursachen & Lösungen:

  1. Falscher Namespace in Datei

    php
    // Falsch
    namespace DoctrineMigrations\Layer0Shared;
    
    // Richtig (für migrations/1_infrastructure/)
    namespace DoctrineMigrations\Infrastructure;
  2. Datei im falschen Ordner

    bash
    # Namespace: DoctrineMigrations\Infrastructure
    # Muss in: migrations/1_infrastructure/
    
    # Verschieben
    mv migrations/2_shared/Version0001_admin.php migrations/1_infrastructure/
  3. doctrine_migrations.yaml falsch

    yaml
    # Prüfen
    doctrine_migrations:
        migrations_paths:
            'DoctrineMigrations\Infrastructure': '%kernel.project_dir%/migrations/1_infrastructure'

"Migration version already registered"

Problem:

bash
Migration version "Version0001" is already registered.

Ursache:

  • Zwei Migrations mit gleichem Namen in verschiedenen Namespaces

Lösung:

bash
# Eindeutige Namen verwenden
Version0001_admin.php      # Infrastructure
Version0001_audit.php      # Shared
Version0001_tenant.php     # Foundation

# Oder Zahlen pro Layer
Version0001_admin.php      # Infrastructure
Version0002_sessions.php   # Infrastructure

Foreign Key Probleme

"Foreign key constraint violation"

Problem:

bash
SQLSTATE[23503]: Foreign key violation

Ursachen:

  1. Falsche Reihenfolge

    php
    // Falsch: Child vor Parent
    $this->addSql('CREATE TABLE admin_sessions (
        admin_id INTEGER NOT NULL REFERENCES admins(id)
    )');
    $this->addSql('CREATE TABLE admins (id SERIAL PRIMARY KEY)');
    
    // Richtig: Parent vor Child
    $this->addSql('CREATE TABLE admins (id SERIAL PRIMARY KEY)');
    $this->addSql('CREATE TABLE admin_sessions (
        admin_id INTEGER NOT NULL REFERENCES admins(id)
    )');
  2. Referenzierte Tabelle existiert nicht

    bash
    # Prüfen ob Parent-Tabelle existiert
    psql -U appiyonadmin -d symfony -c "\dt"

"Cannot drop table, foreign key constraint exists"

Problem:

bash
cannot drop table admins because other objects depend on it

Lösung:

sql
-- Mit CASCADE
DROP TABLE admins CASCADE;

-- Oder in Migration
$this->addSql('DROP TABLE IF EXISTS admin_sessions CASCADE');
$this->addSql('DROP TABLE IF EXISTS admins CASCADE');

Index-Probleme

"Index already exists"

Problem:

bash
SQLSTATE[42P07]: index "idx_admins_email" already exists

Lösung:

php
// IF NOT EXISTS hinzufügen
$this->addSql('CREATE INDEX IF NOT EXISTS idx_admins_email ON admins (email)');

// Oder in down() DROP IF EXISTS
$this->addSql('DROP INDEX IF EXISTS idx_admins_email');

Performance-Issues

Migration dauert sehr lange

Ursachen & Lösungen:

  1. Große Tabellen

    php
    // Indices NACH Daten hinzufügen
    public function up(Schema $schema): void
    {
        $this->addSql('CREATE TABLE large_table (...)');
        // Daten importieren...
        $this->addSql('CREATE INDEX idx_... ON large_table (...) CONCURRENTLY');
    }
  2. Lock-Probleme

    bash
    # Andere Verbindungen beenden
    psql -U postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'symfony' AND pid <> pg_backend_pid();"
  3. Transaktionen zu groß

    php
    // Große Operationen batchen
    public function up(Schema $schema): void
    {
        $batchSize = 1000;
        for ($i = 0; $i < $totalRows; $i += $batchSize) {
            $this->addSql("UPDATE ... LIMIT $batchSize");
        }
    }

Testing Migrations

Test-Database out of sync

Problem:

  • Dev-DB funktioniert, Test-DB nicht

Lösung:

bash
# Test-DB neu aufsetzen
php bin/console doctrine:database:drop --force --env=test
php bin/console doctrine:database:create --env=test
php bin/console doctrine:migrations:migrate --env=test --no-interaction
php bin/console doctrine:schema:validate --env=test

Production-Migrations

Rollback-Plan fehlt

Problem:

  • Migration fehlgeschlagen in Production
  • Kein Rollback möglich

Prevention:

  1. Immer down() implementieren

    php
    public function down(Schema $schema): void
    {
        $this->addSql('DROP TABLE admins CASCADE');
        // Alle up()-Operationen rückgängig machen
    }
  2. Backup vor Migration

    bash
    # Backup erstellen
    pg_dump -U appiyonadmin -Fc symfony > backup_pre_migration.dump
    
    # Migration ausführen
    php bin/console doctrine:migrations:migrate --env=prod
    
    # Bei Fehler: Restore
    pg_restore -U appiyonadmin -d symfony --clean backup_pre_migration.dump
  3. Staging-Test

    bash
    # Migration erst auf Staging testen
    # Dann auf Production

Debugging-Tools

Migration SQL anzeigen

bash
# Dry-Run (zeigt SQL, führt nicht aus)
php bin/console doctrine:migrations:migrate --dry-run

# Nächste Migration
php bin/console doctrine:migrations:migrate next --dry-run

Status detailliert

bash
# Ausführlicher Status
php bin/console doctrine:migrations:status -v

# Zeigt:
# - Available migrations
# - Executed migrations
# - Pending migrations
# - Migration paths

Migration Code ansehen

bash
# Migration-Datei direkt öffnen
cat migrations/1_infrastructure/Version0001_admin.php

# Oder mit Syntax-Highlighting
bat migrations/1_infrastructure/Version0001_admin.php

Checkliste vor Migration

  • [ ] Backup der Datenbank erstellt
  • [ ] Migration auf Dev/Staging getestet
  • [ ] SQL-Code reviewed (dry-run)
  • [ ] down() implementiert
  • [ ] Foreign Key Reihenfolge korrekt
  • [ ] Indices optimiert
  • [ ] Große Operationen gebatched
  • [ ] Rollback-Plan vorhanden
  • [ ] Monitoring aktiv

Recovery-Optionen

Kompletter Reset (nur Dev!)

bash
# Alles löschen und neu
php bin/console doctrine:database:drop --force
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrate --no-interaction
php bin/console doctrine:schema:validate

Partial Reset

bash
# Nur Daten löschen, Schema behalten
psql -U appiyonadmin -d symfony

-- Alle Tables leeren
TRUNCATE TABLE admin_audit_logs, admin_login_attempts, admin_sessions, admin_password_reset_tokens, admins RESTART IDENTITY CASCADE;

Manual Fix

sql
-- doctrine_migration_versions korrigieren
DELETE FROM doctrine_migration_versions;

-- Alle Migrations als executed markieren
INSERT INTO doctrine_migration_versions (version, executed_at, execution_time)
VALUES
    ('DoctrineMigrations\\Infrastructure\\Version0001', NOW(), 1),
    ('DoctrineMigrations\\Shared\\Version0001', NOW(), 1);

Weitere Ressourcen

Built with VitePress