使用迁移删除具有外键的表

时间:2013-06-14 12:37:51

标签: laravel laravel-4

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

我的迁移文件使用外键,如此

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

但我也遇到了错误

7 个答案:

答案 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表的语句以原始格式放置。