【问题标题】:Drop Unique Index Laravel删除唯一索引 Laravel
【发布时间】:2016-07-06 16:24:21
【问题描述】:

我在运行php artisan migrate时不断收到此信息

SQLSTATE[42000]:语法错误或访问冲突:1091 Can't DROP 'email';检查列/键是否存在

虽然我看到我的数据库中存在该电子邮件。


我的迁移脚本。我试图删除唯一约束。

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AlterGuestsTable3 extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('guests', function(Blueprint $table)
        {
            $table->dropUnique('email');

        });

    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('guests', function(Blueprint $table)
        {

            $table->dropUnique('email');

        });
    }

}

我是否忘记清除任何缓存?

对我有什么提示吗?

【问题讨论】:

  • 您是要删除唯一索引,还是完全删除电子邮件列?另外,提醒一下,您的 down 函数也会尝试删除索引,而不是重新创建它。
  • 我只想删除唯一索引。

标签: php laravel laravel-5 laravel-migrations


【解决方案1】:

删除索引时,Laravel 会期望给出索引的全名。

您可以检查数据库中索引的全名,但如果键是由先前的 Laravel 迁移生成的,则其名称应符合单一、简单的命名约定。

以下是documentation 对其命名约定的看法(从 v5.2 开始):

默认情况下,Laravel 会自动为索引分配一个合理的名称。只需将表名、索引列的名称和索引类型连接起来。

我的猜测是这就是您收到错误的原因。没有email 索引,但可能有guests_email_unique 索引。

试试这个迁移:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AlterGuestsTable3 extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('guests', function(Blueprint $table)
        {
            $table->dropUnique('guests_email_unique');

        });

    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('guests', function(Blueprint $table)
        {
            //Put the index back when the migration is rolled back
            $table->unique('email');

        });
    }

}

我知道创建索引时指定列名有点令人困惑,但稍后删除索引时需要提供索引的全名。

请注意,我还调整了 down() 方法,以便通过添加唯一索引来恢复删除唯一索引。

【讨论】:

  • 你救了我的生命伴侣 :)
  • 很高兴为您服务!
【解决方案2】:

通过official documentation您可以看到以下内容:

如果将列数组传递给删除索引的方法,则 常规索引名会根据表名生成, 列和键类型:

Schema::table('geo', function ($table) {
    $table->dropIndex(['state']); // Drops index 'geo_state_index' 
});



您只需在字段名称周围使用[] 即可删除它:

Schema::table('guests', function(Blueprint $table)
{
    $table->dropUnique(['email']);
});

UPD:latest docs for 9.x 仍然相关。

【讨论】:

  • 在我看来这是更好的答案,因为它让 Laravel 使用它创建密钥的过程来确定密钥名称。
  • 与接受的答案相比,这是对我有用的答案(在 L 5.8 上)。
  • 这个答案更好。
  • 这是一个更好的解决方案。它在 7.x 版本中也适用于我。
  • 在 8.x 中完美运行
猜你喜欢
  • 2020-10-01
  • 1970-01-01
  • 2019-10-23
  • 2019-01-13
  • 1970-01-01
  • 2013-09-02
  • 2016-11-19
  • 1970-01-01
  • 2021-02-27
相关资源
最近更新 更多