Creé una tabla usando una migración como esta:
public function up()
{
Schema::create('despatch_discrepancies', function($table) {
$table->increments('id')->unsigned();
$table->integer('pick_id')->unsigned();
$table->foreign('pick_id')->references('id')->on('picks');
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
$table->integer('original_qty')->unsigned();
$table->integer('shipped_qty')->unsigned();
});
}
public function down()
{
Schema::drop('despatch_discrepancies');
}
Necesito cambiar esta tabla y eliminar la referencia y columna de clave externa pick_detail_id
y agregar una nueva columna varchar llamada sku
después de la pick_id
columna.
Entonces, he creado otra migración, que se ve así:
public function up()
{
Schema::table('despatch_discrepancies', function($table)
{
$table->dropForeign('pick_detail_id');
$table->dropColumn('pick_detail_id');
$table->string('sku', 20)->after('pick_id');
});
}
public function down()
{
Schema::table('despatch_discrepancies', function($table)
{
$table->integer('pick_detail_id')->unsigned();
$table->foreign('pick_detail_id')->references('id')->on('pick_details');
$table->dropColumn('sku');
});
}
Cuando ejecuto esta migración, aparece el siguiente error:
[Illuminate \ Database \ QueryException]
SQLSTATE [HY000]: Error general: 1025 Error al cambiar el nombre de './dev_iwms_reboot/despatch_discrepancies' a './dev_iwms_reboot/#sql2-67c-17c464' (errno: 152) (SQL: alter tabledespatch_discrepancies
soltar clave externa pick_detail_id)[PDOException]
SQLSTATE [HY000]: Error general: 1025 Error al cambiar el nombre de './dev_iwms_reboot/despatch_discrepancies' a './dev_iwms_reboot/#sql2-67c-17c464' (errno: 152)
Cuando intento revertir esta migración ejecutando el php artisan migrate:rollback
comando, aparece un Rolled back
mensaje, pero en realidad no está haciendo nada en la base de datos.
¿Alguna idea de lo que podría estar mal? ¿Cómo se suelta una columna que tiene una referencia de clave externa?
fuente
Resulta; cuando crea una clave externa como esta:
$table->integer('pick_detail_id')->unsigned(); $table->foreign('pick_detail_id')->references('id')->on('pick_details');
Laravel nombra de forma única la referencia de clave externa así:
<table_name>_<foreign_table_name>_<column_name>_foreign despatch_discrepancies_pick_detail_id_foreign (in my case)
Por lo tanto, cuando desee eliminar una columna con referencia de clave externa, debe hacerlo así:
$table->dropForeign('despatch_discrepancies_pick_detail_id_foreign'); $table->dropColumn('pick_detail_id');
Actualizar:
Laravel 4.2+ introduce una nueva convención de nomenclatura:
fuente
<table_name>_<column_name>_foreign
convención todavía parece funcionar para 5.1$table->dropIndex('column_name')
.Tenía varias claves externas en mi tabla y luego tuve que eliminar las restricciones de clave externa una por una pasando el nombre de la columna como índice de la matriz en el método down:
public function up() { Schema::table('offices', function (Blueprint $table) { $table->unsignedInteger('country_id')->nullable(); $table->foreign('country_id') ->references('id') ->on('countries') ->onDelete('cascade'); $table->unsignedInteger('stateprovince_id')->nullable(); $table->foreign('stateprovince_id') ->references('id') ->on('stateprovince') ->onDelete('cascade'); $table->unsignedInteger('city_id')->nullable(); $table->foreign('city_id') ->references('id') ->on('cities') ->onDelete('cascade'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('offices', function (Blueprint $table) { $table->dropForeign(['country_id']); $table->dropForeign(['stateprovince_id']); $table->dropForeign(['city_id']); $table->dropColumn(['country_id','stateprovince_id','city_id']); }); }
El uso de la siguiente declaración no funciona
$table->dropForeign(['country_id','stateprovince_id','city_id']);
Porque dropForeign no las considera columnas separadas que queremos eliminar. Entonces tenemos que dejarlos caer uno por uno.
fuente
$table->dropIndex('column_name')
.La clave (para mí) para resolver esto fue asegurarse de que el comando $ table-> dropForeign () recibiera el nombre de relación correcto, no necesariamente el nombre de la columna. Usted no desea pasar el nombre de la columna, como sería mi humilde opinión mucho más intuitivo.
Lo que funcionó para mí fue:
$table->dropForeign('local_table_foreign_id_foreign'); $table->column('foreign_id');
Entonces, la cadena que pasé a dropForeign () que funcionó para mí estaba en el formato de:
[tabla local] _ [campo de clave externa] _extranjero
Si tiene acceso a una herramienta como Sequel Pro o Navicat, será muy útil poder visualizarlas.
fuente
Algo que se me ocurrió fue que no sabía dónde poner el
Schema::table
bloque.Más tarde descubrí que la clave está en el error SQL:
[Illuminate\Database\QueryException] SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table if exists `lu_benefits_categories`)
Entonces el
Schema::table
bloque debe ir endown()
función de lalu_benefits_categories
migración y antes de laSchema::dropIfExists
línea:public function down() { Schema::table('table', function (Blueprint $table) { $table->dropForeign('table_category_id_foreign'); $table->dropColumn('category_id'); }); Schema::dropIfExists('lu_benefits_categories'); }
Después de eso, el
php artisan migrate:refresh
ophp artisan migrate:reset
hará el truco.fuente