Reputation: 906
I have a table (named j_stones
) which consists of 5 fields :
id(primary key)
j_stones_type(foreign-key)
shape
size
carat
I want to make each row unique, so I created a migration to do this :
public function up()
{
Schema::table('j_stones', function (Blueprint $table) {
$table->unique(['j_stone_types_id','shape','size','carat']);
});
}
This works perfectly but when I try to rollback I get the following error:
1[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1553 Cannot drop index
'j_stones_j_stone_types_id_shape_size_carat_unique': needed in a foreign key constraint (SQL: alter table
j_stones
drop indexj_stones_j_stone_types_id_shape_size_carat_unique
)[PDOException] SQLSTATE[HY000]: General error: 1553 Cannot drop index 'j_stones_j_stone_types_id_shape_size_carat_unique': needed in a foreign key constraint'
This is my rollback code:
public function down()
{
Schema::table('j_stones', function (Blueprint $table) {
$table->dropUnique(['j_stone_types_id','shape','size','carat']);
});
}
I tried disabling foreign key contraint like this:
public function down()
{
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
Schema::table('j_stones', function (Blueprint $table) {
$table->dropUnique(['j_stone_types_id','shape','size','carat']);
});
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}
And also like this :
public function down()
{
Schema::disableForeignKeyConstraints();
Schema::table('j_stones', function (Blueprint $table) {
$table->dropUnique(['j_stone_types_id','shape','size','carat']);
});
Schema::enableForeignKeyConstraints();
}
But still error keeps happening on rollback.
Am using MySql with InnoDb.
Please advice.
Edit:
I got the rollback to work using the below hack , but am still looking for the proper solution :
public function down()
{
Schema::table('j_stones', function (Blueprint $table) {
$table->dropForeign(['j_stone_types_id']);
$table->dropUnique(['j_stone_types_id','shape','size','carat']);
});
}
Upvotes: 5
Views: 6616
Reputation: 24035
public function up() {
Schema::table('contact_tags', function (Blueprint $table) {
$table->unique(['tag_id', 'contact_id'], 'tag_contact_unique'); //so that contact cannot have the same tag multiple times
});
}
public function down() {
Schema::table('contact_tags', function (Blueprint $table) {
//THE FOLLOWING 2 COMMANDS ARE THE WORKAROUND
//Although this feels weird, we first need to add the missing indexes:
$table->index('tag_id', 'tag_id_foreign');
$table->index('contact_id', 'contact_id_foreign');
//Now proceed with the main part of this "down" command to drop the unique index:
$table->dropUnique('tag_contact_unique');
});
}
Upvotes: 13
Reputation: 1059
I was facing the same issue. The way I solved it was by doing the following inside the down()
function of the migration:
E.g.
public function down()
{
Schema::table('j_stones', function (Blueprint $table) {
$table->dropForeign(/* Foreign key name */);
});
Schema::table('j_stones', function (Blueprint $table) {
$table->dropUnique(/* Array of fields for the composite index */);
});
Schema::table('j_stones', function (Blueprint $table) {
/* Creating back the foreign key here, just like the way it was before running the migration */
});
}
This way, every time I rolled back the migration, my DB and the foreign key returned to their previous state.
Upvotes: 2
Reputation: 21
I just encountered the same problem and this worked for me:
public function down()
{
Schema::table('j_stones', function (Blueprint $table) {
$table->index('j_stone_types_id']);
$table->dropUnique(['j_stone_types_id','shape','size','carat']);
});
}
So first add a new index on the column that is needed for the foreign key constraint, and then you can drop the compound key.
Upvotes: 2