I have a table workflows with an auto-incrementing primary key called 'click_id'
. I would like to add a field ‘id’ at the beginning of the table and make that the auto incrementing primary key.
This is the migration that fails:
Schema::table('workflows', function (Blueprint $table) {
$table->unsignedBigInteger('click_id')->change();
$table->dropPrimary('click_id');
$table->bigIncrements('id')->first();
$table->unique(['click_id','review_id']);
});
The error is
SQLSTATE[42000]: Syntax error or access violation: 1068 Multiple primary key defined (Connection: mysql, SQL: alter table `workflows` add `id` bigint unsigned not null auto_increment primary key first)
This suggests that the dropPrimary()
command is not completing before laravel continues onto the next line of the migration.
The only workaround I’ve found to be sucessful is to split it into two separate chunks within the up()
method.
public function up(): void
{
Schema::table('workflows', function (Blueprint $table) {
$table->unsignedBigInteger('click_id')->change();
$table->dropPrimary('click_id');
});
Schema::table('workflows', function (Blueprint $table) {
$table->bigIncrements('id')->first();
$table->unique(['click_id','review_id']);
});
}
public function down(): void
{
Schema::table('workflows', function (Blueprint $table) {
$table->dropUnique('workflows_click_id_review_id_unique');
$table->unsignedBigInteger('id')->change();
$table->dropPrimary('id');
$table->dropColumn('id');
});
DB::statement('ALTER TABLE `workflows` CHANGE `click_id` `click_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, add PRIMARY KEY (`click_id`)');
}
Why does it not work as expected when within a single closure?
System: Laravel 10, MariaDB 10.4.32
2
Answers
Starting with this migration:
This is the output that you get when dd’ing inside the
build
method of theBlueprint
class (here)As you can see, this does NOT follow the order of our instructions! The dropping of the primary key and the index queries get pushed to the end of the array.
Further research is needed to understand why they made this choice.
If you keep following the instruction pointer, you end up here:
Even without over-analyzing each of these calls, it seems the laravel chooses a specific order when it compiles the list of queries to run. That makes it necessary to separate the changes into 2
Schema::table(...)
calls.It seems like you’re trying to change the primary key of the workflows table in your Laravel migration.there are a couple of issues in your migration code that might be causing the problem:
Here are the corrected code for your migration: