Laravel 5.1 迁移和播种无法截断外键约束中引用的 table
Laravel 5.1 Migration and Seeding Cannot truncate a table referenced in a foreign key constraint
我正在尝试 运行 迁移(见下文)并为数据库播种,但是当我 运行
php artisan migrate --seed
我收到这个错误:
Migration table created successfully.
Migrated: 2015_06_17_100000_create_users_table
Migrated: 2015_06_17_200000_create_password_resets_table
Migrated: 2015_06_17_300000_create_vehicles_table
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table
referenced in a foreign key constraint (`app`.`vehicles`, CONSTRAINT `vehic
les_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `app`.`users` (`id`
)) (SQL: truncate `users`)
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table
referenced in a foreign key constraint (`app`.`vehicles`, CONSTRAINT `vehic
les_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `app`.`users` (`id`
))
我查看了这个错误的含义,还找到了 of other people running into the same problem, even just related to using MySQL 和他们的解决方案,但应用:
DB::statement('SET FOREIGN_KEY_CHECKS=0;'); and
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
在 down() 中似乎不起作用,当我 运行 在 MySQL 中描述时,table 看起来是正确的。
正确命名迁移以确保首先迁移用户 table,然后迁移车辆,以便可以应用外键,并且正确设置的 table 会建议迁移是 运行,但随后发生错误。我删除并重新创建了数据库并再次尝试,结果相同。我也不明白为什么它试图 t运行cate 在数据库的第一次迁移和种子上,我不会想到当你试图 运行 php artisan migrate:refresh --seed.
// 2015_06_17_100000_create_users_table.php
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('username', 60)->unique();
$table->string('email', 200)->unique();
$table->string('password', 255);
$table->string('role')->default('user');
$table->rememberToken();
$table->timestamps();
});
}
}
public function down()
{
Schema::drop('users');
}
// 2015_06_17_300000_create_vehicles_table.php
class CreateVehiclesTable extends Migration
{
public function up()
{
Schema::create('vehicles', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('make');
$table->string('model');
$table->string('year');
$table->string('color');
$table->string('plate');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
});
}
}
public function down()
{
Schema::drop('vehicles');
}
如错误所述,您不能截断外键引用的表。删除应该有效...
DB::table('some_table')->delete();
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
App\User::truncate();
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
而且有效!
到clear
一个table
使用Eloquent
:
Model::query()->delete();
使用默认用户模型的示例
User::query()->delete();
这是每次都对我有用的方法。
添加外键时,请确保添加 cascade
。
语法是这样的
$table->foreign('column')->references('id')->on('table_name')->onDelete('cascade');
确保将 id
替换为适用于您的任何字段。
现在在 运行 播种之前添加这个而不是 trucate
DB::statement('DELETE FROM table_name');
它将删除所有数据。
希望这有帮助。
你可以使用
DB::table('your_table_name')->delete();
清空table,这不会删除table结构。但是自增id不会从初始号开始。
您可以将其删除。
$table->dropForeign('posts_user_id_foreign');
下降前
Schema::disableForeignKeyConstraints();
和关闭前运行方法
Schema::enableForeignKeyConstraints();
我正在使用 Laravel 7.x,这对我有用。不用说,它应该只用于开发。要了解更多信息,请查看 here.
DatabaseSeeder.php
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
// the Eloquent part and disabling and enabling of foreign keys is only intended for development
Eloquent::unguard();
//disable foreign key check for this connection before running seeders
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
$this->call(RolesTableSeeder::class);
$this->call(UsersTableSeeder::class);
// supposed to only apply to a single connection and reset it's self
// but I like to explicitly undo what I've done for clarity
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
}
}
我在角色和权限设置方面遇到了同样的问题,这就是我所做的,并且效果如我所愿。 Truncate() 会将增量列重置为 1,但抛出外键错误,而另一方面 delete 工作正常但不会重置增量列,所以我在我的 Seeder 文件中执行了以下操作(即 RoleSeeder.php 在我的情况)
1. [ delete() 方法]
$roles = [];
... // Some foreach statement to prepare an array of data for DB insert()
// Delete and Reset Table
DB::table('roles')->delete();
DB::statement("ALTER TABLE `roles` AUTO_INCREMENT = 1");
// Insert into table
DB::table('roles')->insert($roles);
这将级联附加到 角色 table 的所有其他 child table。在我的例子中 users_roles table。这样我就避免了禁用和启用外键检查。
2。要记住的事情/第二种方法[ truncate() 方法]
如果您不打算删除存储在 child 的 table 中的所有数据(在我的例子中是 users_roles table).. . 您可以使用 truncate() 然后在 DatabaseSeeders.php 文件中禁用和启用外键检查。当我对此进行测试并且 users_roles 数据完好无损时,受影响角色的种子 table.
//RoleSeeders.php File
$roles = [];
... // Some foreach statement to prepare an array of data for DB insert()
// Truncate Table
DB::table('roles')->truncate();
// Insert into table
DB::table('roles')->insert($roles);
然后在 DatabaseSeeder.php 文件中,你做;
public function run()
{
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
$this->call([
RoleSeeder::class,
]);
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
}
但我更喜欢 delete() 方法,因为我不必 disable/enable 外键检查
我正在尝试 运行 迁移(见下文)并为数据库播种,但是当我 运行
php artisan migrate --seed
我收到这个错误:
Migration table created successfully.
Migrated: 2015_06_17_100000_create_users_table
Migrated: 2015_06_17_200000_create_password_resets_table
Migrated: 2015_06_17_300000_create_vehicles_table
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table
referenced in a foreign key constraint (`app`.`vehicles`, CONSTRAINT `vehic
les_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `app`.`users` (`id`
)) (SQL: truncate `users`)
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1701 Cannot truncate a table
referenced in a foreign key constraint (`app`.`vehicles`, CONSTRAINT `vehic
les_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `app`.`users` (`id`
))
我查看了这个错误的含义,还找到了
DB::statement('SET FOREIGN_KEY_CHECKS=0;'); and
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
在 down() 中似乎不起作用,当我 运行 在 MySQL 中描述时,table 看起来是正确的。
正确命名迁移以确保首先迁移用户 table,然后迁移车辆,以便可以应用外键,并且正确设置的 table 会建议迁移是 运行,但随后发生错误。我删除并重新创建了数据库并再次尝试,结果相同。我也不明白为什么它试图 t运行cate 在数据库的第一次迁移和种子上,我不会想到当你试图 运行 php artisan migrate:refresh --seed.
// 2015_06_17_100000_create_users_table.php
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('username', 60)->unique();
$table->string('email', 200)->unique();
$table->string('password', 255);
$table->string('role')->default('user');
$table->rememberToken();
$table->timestamps();
});
}
}
public function down()
{
Schema::drop('users');
}
// 2015_06_17_300000_create_vehicles_table.php
class CreateVehiclesTable extends Migration
{
public function up()
{
Schema::create('vehicles', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('make');
$table->string('model');
$table->string('year');
$table->string('color');
$table->string('plate');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
});
}
}
public function down()
{
Schema::drop('vehicles');
}
如错误所述,您不能截断外键引用的表。删除应该有效...
DB::table('some_table')->delete();
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
App\User::truncate();
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
而且有效!
到clear
一个table
使用Eloquent
:
Model::query()->delete();
使用默认用户模型的示例
User::query()->delete();
这是每次都对我有用的方法。
添加外键时,请确保添加 cascade
。
语法是这样的
$table->foreign('column')->references('id')->on('table_name')->onDelete('cascade');
确保将 id
替换为适用于您的任何字段。
现在在 运行 播种之前添加这个而不是 trucate
DB::statement('DELETE FROM table_name');
它将删除所有数据。 希望这有帮助。
你可以使用
DB::table('your_table_name')->delete();
清空table,这不会删除table结构。但是自增id不会从初始号开始。
您可以将其删除。
$table->dropForeign('posts_user_id_foreign');
下降前
Schema::disableForeignKeyConstraints();
和关闭前运行方法
Schema::enableForeignKeyConstraints();
我正在使用 Laravel 7.x,这对我有用。不用说,它应该只用于开发。要了解更多信息,请查看 here.
DatabaseSeeder.php
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
// the Eloquent part and disabling and enabling of foreign keys is only intended for development
Eloquent::unguard();
//disable foreign key check for this connection before running seeders
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
$this->call(RolesTableSeeder::class);
$this->call(UsersTableSeeder::class);
// supposed to only apply to a single connection and reset it's self
// but I like to explicitly undo what I've done for clarity
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
}
}
我在角色和权限设置方面遇到了同样的问题,这就是我所做的,并且效果如我所愿。 Truncate() 会将增量列重置为 1,但抛出外键错误,而另一方面 delete 工作正常但不会重置增量列,所以我在我的 Seeder 文件中执行了以下操作(即 RoleSeeder.php 在我的情况)
1. [ delete() 方法]
$roles = [];
... // Some foreach statement to prepare an array of data for DB insert()
// Delete and Reset Table
DB::table('roles')->delete();
DB::statement("ALTER TABLE `roles` AUTO_INCREMENT = 1");
// Insert into table
DB::table('roles')->insert($roles);
这将级联附加到 角色 table 的所有其他 child table。在我的例子中 users_roles table。这样我就避免了禁用和启用外键检查。
2。要记住的事情/第二种方法[ truncate() 方法]
如果您不打算删除存储在 child 的 table 中的所有数据(在我的例子中是 users_roles table).. . 您可以使用 truncate() 然后在 DatabaseSeeders.php 文件中禁用和启用外键检查。当我对此进行测试并且 users_roles 数据完好无损时,受影响角色的种子 table.
//RoleSeeders.php File
$roles = [];
... // Some foreach statement to prepare an array of data for DB insert()
// Truncate Table
DB::table('roles')->truncate();
// Insert into table
DB::table('roles')->insert($roles);
然后在 DatabaseSeeder.php 文件中,你做;
public function run()
{
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
$this->call([
RoleSeeder::class,
]);
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
}
但我更喜欢 delete() 方法,因为我不必 disable/enable 外键检查