laravel 使用迁移删除带有外键的表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17108671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 02:30:41  来源:igfitidea点击:

Using migrations to delete table with foreign key

laravellaravel-4

提问by BigJobbies

Im trying to roll back my migrations.

我正在尝试回滚我的迁移。

My migrations file uses foreign keys like so

我的迁移文件像这样使用外键

$table->foreign('user_one')->references('id')->on('users');
$table->foreign('user_two')->references('id')->on('users');

My down() function is like so

我的 down() 函数是这样的

public function down()
{
    Schema::drop('pm_convo');
    Schema::drop('pm_convo_replys');
}

When i run my migrate command

当我运行迁移命令时

php artisan migrate:refresh --seed --env=local

I am getting the following error

我收到以下错误

SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constraint fails (SQL: drop table `pm_convo`) 

Im not exactly sure what to do to fix this.

我不确定该怎么做才能解决这个问题。

Edit:

编辑:

I have tried: $table->dropForeign('pm_convo_user_one_foreign');

我试过了: $table->dropForeign('pm_convo_user_one_foreign');

But im getting errors with that as well

但我也遇到了错误

回答by Eric Chan

I think this is a better way to do it:

我认为这是一个更好的方法:

public function down()
{
    DB::statement('SET FOREIGN_KEY_CHECKS = 0');
    Schema::dropIfExists('tableName');
    DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}

回答by Nils Werner

pm_convo_replyshas a foreign key that references pm_convo, thus you cannot delete pm_convofirstwithout violating a foreign key constraint in pm_convo_replys.

pm_convo_replys有一个外键引用pm_convo,所以你不能删除pm_convo第一个不违反外键约束pm_convo_replys

To delete both you need to delete pm_convo_replysfirst.

要同时删除您需要删除pm_convo_replys第一

public function down()
{
    Schema::drop('pm_convo_replys');
    Schema::drop('pm_convo');
}

回答by Dinuka Thilanga

I also faced these kind of issues. Migration file order is the main issue here. The best way is to create migration files one by one. Main entities should be created first. Migration should be refreshed with every migrate file creation. (with php artisan migrate:refresh)

我也遇到过这类问题。迁移文件顺序是这里的主要问题。最好的办法是一一创建迁移文件。应首先创建主要实体。每次创建迁移文件时都应刷新迁移。(与php artisan migrate:refresh

According to @abkrim and @Eric

根据@abkrim 和@Eric

public function down()
{
    Schema::disableForeignKeyConstraints();
    Schema::drop('tableName');
    Schema::enableForeignKeyConstraints();
}

回答by eithed

I think this is the most correct approach:

我认为这是最正确的方法:

public function down()
{
    Schema::table('[table]', function (Blueprint $table) {
        $table->dropForeign('[table]_[column]_foreign');
        $table->dropColumn('[column]');
    });
}

回答by ken

prefer to do it this way

更喜欢这样做

    Schema::dropIfExists('tableNameChild');
    Schema::drop('tableNameParents');

回答by Iván Sánchez

Important, this is for Laravel 5.4.

重要的是,这是针对 Laravel 5.4 的

According to the docs

根据文档

To drop a foreign key, you may use the dropForeign method. Foreign key constraints use the same naming convention as indexes. So, we will concatenate the table name and the columns in the constraint then suffix the name with "_foreign"

要删除外键,您可以使用 dropForeign 方法。外键约束使用与索引相同的命名约定。因此,我们将连接表名和约束中的列,然后在名称后缀“_foreign”

$table->dropForeign('posts_user_id_foreign');

Or, you may pass an array value which will automatically use the conventional constraint name when dropping:

或者,您可以传递一个数组值,该值将在删除时自动使用常规约束名称:

$table->dropForeign(['user_id']);

I personally prefer the second one because of simplicity

我个人更喜欢第二个因为简单

回答by Koushik Das

You can do that thing very easily if you added cascadeon the foeign keywhen creating the table. If you did it, then you can remove the table very easily without something like this for PostgreSQL.

如果您在创建表时添加了cascade,您可以很容易地做到这一点foeign key。如果你这样做了,那么你可以很容易地删除表,而不需要像 PostgreSQL 这样的东西。

DB::statement("drop table tableName if exists cascade");

All you have to do is to put the statement for SQL table in the raw format.

您所要做的就是将 SQL 表的语句置于原始格式中。