我正在尝试回滚我的迁移。
我的迁移文件使用外键,如此
$table->foreign('user_one')->references('id')->on('users');
$table->foreign('user_two')->references('id')->on('users');
我的down()函数是这样的
public function down()
{
Schema::drop('pm_convo');
Schema::drop('pm_convo_replys');
}
当我运行我的迁移命令时
php artisan migrate:refresh --seed --env=local
我收到以下错误
SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table `pm_convo`)
我不确定如何解决这个问题。
修改
我尝试过:$table->dropForeign('pm_convo_user_one_foreign');
但我也遇到了错误
答案 0 :(得分:69)
我认为这是一种更好的方法:
public function down()
{
DB::statement('SET FOREIGN_KEY_CHECKS = 0');
Schema::dropIfExists('tableName');
DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}
答案 1 :(得分:57)
pm_convo_replys
有一个引用pm_convo
的外键,因此无法在不违反pm_convo
中的外键约束的情况下首先删除pm_convo_replys
。
要删除这两项内容,您需要首先删除pm_convo_replys
。
public function down()
{
Schema::drop('pm_convo_replys');
Schema::drop('pm_convo');
}
答案 2 :(得分:23)
我也遇到过这类问题。迁移文件顺序是此处的主要问题。最好的方法是逐个创建迁移文件。应首先创建主要实体。每次创建迁移文件时都应刷新迁移。 (使用php artisan migrate:refresh
)
根据@abkrim和@Eric
public function down()
{
Schema::disableForeignKeyConstraints();
Schema::drop('tableName');
Schema::enableForeignKeyConstraints();
}
答案 3 :(得分:8)
我认为这是最正确的方法:
public function down()
{
Schema::table('[table]', function (Blueprint $table) {
$table->dropForeign('[table]_[column]_foreign');
$table->dropColumn('[column]');
});
}
答案 4 :(得分:3)
喜欢这样做
Schema::dropIfExists('tableNameChild');
Schema::drop('tableNameParents');
答案 5 :(得分:1)
重要的是,这适用于Laravel 5.4 。
根据docs
要删除外键,可以使用dropForeign方法。外键约束使用与索引相同的命名约定。因此,我们将连接约束中的表名和列,然后将名称后缀为" _foreign"
foreach ($addplus as $key => $string) {
$t = explode("<mrow>", $string);
$final = "";
for($i = 1; $i < count($t); ++$i) {
if(substr($t[$i], 0, 4) != '<mo>') {
$final = $final.$t[$i-1].'<mrow><mo>+</mo>'.$t[$i];
}
else {
$final = $final.'<mrow>'.$t[$i];
}
}
$addplus[$key] = $final;
}
或者,您可以传递一个数组值,在删除时会自动使用传统的约束名称:
$table->dropForeign('posts_user_id_foreign');
我个人更喜欢第二个,因为简单
答案 6 :(得分:0)
如果在创建表时在cascade
上添加了foeign key
,则可以非常轻松地完成此操作。如果这样做了,那么对于PostgreSQL这样的东西,您可以很容易地删除表。
DB::statement("drop table tableName if exists cascade");
您要做的就是将SQL表的语句以原始格式放置。