58

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

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');

But im getting errors with that as well

4

7 回答 7

83

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

public function down()
{
    DB::statement('SET FOREIGN_KEY_CHECKS = 0');
    Schema::dropIfExists('tableName');
    DB::statement('SET FOREIGN_KEY_CHECKS = 1');
}
于 2013-09-03T10:38:44.433 回答
75

pm_convo_replys has a foreign key that references pm_convo, thus you cannot delete pm_convo first without violating a foreign key constraint in pm_convo_replys.

To delete both you need to delete pm_convo_replys first.

public function down()
{
    Schema::drop('pm_convo_replys');
    Schema::drop('pm_convo');
}
于 2013-06-14T13:33:54.563 回答
37

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

根据@abkrim 和@Eric

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

或更安全:

protected function dropColumn($table, $column) {
    try {
        Schema::disableForeignKeyConstraints();
        Schema::table($table, function (Blueprint $tbl) use ($column) {
            $tbl->dropColumn($column);
        });
    } catch (Illuminate\Database\QueryException $e)
    {
        Schema::table($table, function (Blueprint $tbl) use ($column) {
            $tbl->dropConstrainedForeignId($column);
        });
    } finally {
        Schema::enableForeignKeyConstraints();
    }
}

public function down() {
    $this->dropColumn('users', 'foreign_column');
}
于 2017-01-01T17:35:27.433 回答
13

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

public function down()
{
    Schema::table('[table]', function (Blueprint $table) {
        $table->dropForeign('[table]_[column]_foreign');
        $table->dropColumn('[column]');
    });
}
于 2017-06-26T13:40:17.563 回答
3

更喜欢这样做

    Schema::dropIfExists('tableNameChild');
    Schema::drop('tableNameParents');
于 2015-07-06T20:06:12.820 回答
2

cascade如果您在foeign key创建表时添加,您可以非常轻松地完成此操作。如果你这样做了,那么你可以很容易地删除表,而不需要像 PostgreSQL 这样的东西。

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

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

于 2018-11-03T05:27:07.690 回答
2

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

根据文档

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

$table->dropForeign('posts_user_id_foreign');

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

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

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

于 2018-05-28T22:00:20.180 回答