2013-06-14 27 views
32

Sto tentando di ripristinare le mie migrazioni.Utilizzo delle migrazioni per eliminare la tabella con chiave esterna

Il mio file migrazioni utilizza chiavi esterne in questo modo

funzione
$table->foreign('user_one')->references('id')->on('users'); 
$table->foreign('user_two')->references('id')->on('users'); 

My verso il basso() è in questo modo

public function down() 
{ 
    Schema::drop('pm_convo'); 
    Schema::drop('pm_convo_replys'); 
} 

Quando eseguo il mio comando migrate

php artisan migrate:refresh --seed --env=local 

io sono sempre il seguente errore

SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table `pm_convo`) 

Non sono sicuro di cosa fare per risolvere il problema.

Edit:

ho provato: $table->dropForeign('pm_convo_user_one_foreign');

Ma im ottenendo gli errori con quello pure

+0

Avete un'altra tabella che ha una chiave esterna che fa riferimento a 'pm_convo'? –

+0

Sì. C'è una tabella chiamata pm_convo_replys che ha $ table-> foreign ('c_id_fk') -> riferimenti ('id') -> on ('pm_convo'); – BigJobbies

+0

In tal caso, attiva le due chiamate 'drop'. –

risposta

46

pm_convo_replys ha una chiave esterna che fa riferimento pm_convo, in tal modo si Non è possibile cancellare pm_convo primo senza violare un vincolo di chiave esterna in pm_convo_replys.

Per eliminare entrambi è necessario eliminare pm_convo_replys prima.

public function down() 
{ 
    Schema::drop('pm_convo_replys'); 
    Schema::drop('pm_convo'); 
} 
57

credo che questo sia un modo migliore per farlo:

public function down() 
{ 
    DB::statement('SET FOREIGN_KEY_CHECKS = 0'); 
    Schema::dropIfExists('tableName'); 
    DB::statement('SET FOREIGN_KEY_CHECKS = 1'); 
} 
+4

Questo è un modo più semplice per farlo con sicurezza se si hanno a che fare con molte chiavi esterne, ma funzionerà con tutti i tipi di database? Inoltre, non sarebbe possibile durante lo sviluppo se le migrazioni non fossero del tutto esatte a lasciare accidentalmente assenti i controlli delle chiavi esterne? Personalmente sento il suo pulitore solo per ordinarli correttamente – WebweaverD

+0

Thx, questa soluzione ha risolto il mio problema con un troncamento sul mio seed di database. – ke20

+0

Penso che non sia saggio usare qui "dropIfExists". In linea di principio, trovo che sia meglio scrivere le migrazioni che si basano sullo stato corrente del database essendo ciò che si pensa che sia. Se lo stato del database è diverso da quello che ti aspetti quando viene eseguita la funzione 'down' (diciamo che la tabella non esiste), allora c'è la possibilità che ci sia qualcosa di terribilmente sbagliato nella funzione' up', e hai davvero bisogno di risolvilo prima –

3

preferiscono farlo in questo modo

Schema::dropIfExists('tableNameChild'); 
    Schema::drop('tableNameParents'); 
5

ho anche affrontato questo tipo di problemi. L'ordine dei file di migrazione è il problema principale qui. Il modo migliore è creare i file di migrazione uno per uno. Le entità principali dovrebbero essere create prima. La migrazione dovrebbe essere aggiornata con ogni migrazione del file. (Con php artisan migrate:refresh)

Secondo @abkrim e @Eric

public function down() 
{ 
    Schema::disableForeignKeyConstraints(); 
    Schema::drop('tableName'); 
    Sch‌​ema::enableForeignKe‌​yConstraints(); 
} 
2

Penso che questo sia l'approccio più corretto:

public function down() 
{ 
    Schema::table('[table]', function (Blueprint $table) { 
     $table->dropForeign('[table]_[column]_foreign'); 
     $table->dropColumn('[column]'); 
    }); 
} 
Problemi correlati