Troubleshooting Migrations
Häufige Probleme und Lösungen bei Doctrine-Migrationen.
Migration erstellen
"No changes detected"
Problem:
php bin/console doctrine:migrations:diff
# No changes detectedUrsachen & Lösungen:
Entity nicht gemapped
bash# Mapping-Info prüfen php bin/console doctrine:mapping:info # Sollte alle Entities zeigen # Wenn nicht: doctrine.yaml prüfenCache-Problem
bashphp bin/console cache:clear php bin/console doctrine:migrations:diffSchema bereits aktuell
bash# Diff manuell anzeigen php bin/console doctrine:schema:update --dump-sql # Wenn leer → alles aktuellFalsches 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 in5_domain/
Ursache:
- Doctrine wählt automatisch ersten Namespace aus
doctrine_migrations.yaml
Lösung:
Option 1: Migration manuell verschieben
# 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
# 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:
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:
public function up(Schema $schema): void
{
// SQL hinzufügen
$this->addSql('CREATE TABLE ...');
}"Migration ... already executed"
Problem:
Migration ... has already been executed.Ursache:
- Eintrag in
doctrine_migration_versionsTabelle vorhanden
Lösungen:
Option 1: Version-Flag entfernen
-- 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
php bin/console doctrine:migrations:version DoctrineMigrations\\Infrastructure\\Version0001 --add --no-interaction"Table already exists"
Problem:
SQLSTATE[42P07]: Duplicate table: 7 ERROR: relation "admins" already existsUrsachen & Lösungen:
Tabelle wurde manuell erstellt
sql-- Tabelle löschen DROP TABLE admins CASCADE; -- Migration erneut ausführen php bin/console doctrine:migrations:migrateMigration 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:migrateMigration 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:
SQLSTATE[42601]: Syntax errorDebugging:
# 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.phpHäufige Fehler:
// 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:
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:
-- Manuell als executed markieren
INSERT INTO doctrine_migration_versions (version, executed_at, execution_time)
VALUES ('DoctrineMigrations\\Infrastructure\\Version0001', NOW(), 1);down() wirft Exception
Problem:
public function down(Schema $schema): void
{
$this->throwIrreversibleMigrationException();
}Lösung:
- Entweder down() implementieren
- Oder Datenbank neu aufsetzen:
php bin/console doctrine:database:drop --force
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrateSchema Out of Sync
"Database schema is not in sync"
Problem:
php bin/console doctrine:schema:validate
[FAIL] The database schema is not in sync with the current mapping files.Diagnose:
# Unterschiede anzeigen
php bin/console doctrine:schema:update --dump-sqlLösungen:
Option 1: Neue Migration (empfohlen)
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrateOption 2: Direkt updaten (nur Dev!)
php bin/console doctrine:schema:update --forceOption 3: Datenbank neu aufsetzen
php bin/console doctrine:database:drop --force
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrateMigration-Status Probleme
"Inconsistent migration status"
Problem:
php bin/console doctrine:migrations:status
# Shows: 3 available, 5 executedUrsache:
- Migrations gelöscht, aber Flag noch in DB
- Oder Migrations hinzugefügt, aber nicht executed
Lösung:
-- 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:
SQLSTATE[42P01]: Undefined table: relation "doctrine_migration_versions" does not existLösung:
# 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-interactionNamespace-Probleme
"Class ... not found"
Problem:
Class "DoctrineMigrations\Infrastructure\Version0001" not foundUrsachen & Lösungen:
Falscher Namespace in Datei
php// Falsch namespace DoctrineMigrations\Layer0Shared; // Richtig (für migrations/1_infrastructure/) namespace DoctrineMigrations\Infrastructure;Datei im falschen Ordner
bash# Namespace: DoctrineMigrations\Infrastructure # Muss in: migrations/1_infrastructure/ # Verschieben mv migrations/2_shared/Version0001_admin.php migrations/1_infrastructure/doctrine_migrations.yaml falsch
yaml# Prüfen doctrine_migrations: migrations_paths: 'DoctrineMigrations\Infrastructure': '%kernel.project_dir%/migrations/1_infrastructure'
"Migration version already registered"
Problem:
Migration version "Version0001" is already registered.Ursache:
- Zwei Migrations mit gleichem Namen in verschiedenen Namespaces
Lösung:
# 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 # InfrastructureForeign Key Probleme
"Foreign key constraint violation"
Problem:
SQLSTATE[23503]: Foreign key violationUrsachen:
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) )');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:
cannot drop table admins because other objects depend on itLösung:
-- 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:
SQLSTATE[42P07]: index "idx_admins_email" already existsLösung:
// 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:
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'); }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();"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:
# 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=testProduction-Migrations
Rollback-Plan fehlt
Problem:
- Migration fehlgeschlagen in Production
- Kein Rollback möglich
Prevention:
Immer down() implementieren
phppublic function down(Schema $schema): void { $this->addSql('DROP TABLE admins CASCADE'); // Alle up()-Operationen rückgängig machen }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.dumpStaging-Test
bash# Migration erst auf Staging testen # Dann auf Production
Debugging-Tools
Migration SQL anzeigen
# 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-runStatus detailliert
# Ausführlicher Status
php bin/console doctrine:migrations:status -v
# Zeigt:
# - Available migrations
# - Executed migrations
# - Pending migrations
# - Migration pathsMigration Code ansehen
# Migration-Datei direkt öffnen
cat migrations/1_infrastructure/Version0001_admin.php
# Oder mit Syntax-Highlighting
bat migrations/1_infrastructure/Version0001_admin.phpCheckliste 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!)
# 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:validatePartial Reset
# 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
-- 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);