【问题标题】:Foreign Key constraint is incorrectly formed - Laravel 7外键约束的格式不正确 - Laravel 7
【发布时间】:2020-09-24 11:09:46
【问题描述】:

我试图在 Laravel 7 中使用新的迁移将列设置为 foreignID,但我遇到了一个奇怪的错误。

我会一步一步来,这样大家就清楚了。

首先,我使用下面的迁移创建了一个问题表 -

        Schema::create('questions', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('slug')->unique();
            $table->longText('body');
            $table->unsignedInteger('views')->default(0);
            $table->unsignedInteger('answers_count')->default(0);
            $table->integer('votes')->default(0);
            $table->integer('best_answer_id')->nullable();
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->timestamps();
        });

在上表中,user_id 是一个外键,包含在 users 表中的用户 ID 中。这工作得很好。

然后我使用以下迁移创建了一个Answers

       Schema::create('answers', function (Blueprint $table) {
            $table->id();
            $table->integer('question_id');
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->longText('body');
            $table->integer('votes_count')->default(0);
            $table->timestamps();
        });

现在我想要的是,在 Questions 表中名为 best_answer_id 的列应该是限制在 Answers 表中的 id 的外键。

为了实现这一点,我创建了一个名为 make_foreign_best_answers_id_in_questions 的新迁移,迁移在这里:

        Schema::table('questions', function (Blueprint $table) {
            $table->foreign('best_answer_id')
                    ->references('id')
                    ->on('answers')
                    ->onDelete('SET NULL');
        });

据我所知,这应该将 best_answer_id 列设置为应该引用答案表中的 ID 的外部 ID。

在运行 `php artisan migrate`` 时会抛出一个奇怪的错误,内容如下:

SQLSTATE[HY000]: 一般错误: 1005 Can't create table laravel-qa.questions (errno: 150 "外键约束格式不正确") (SQL: alter table questions add constraint questions_best_answer_id_foreign删除 SET NULL 时外键 (best_answer_id) 引用 answers (id)

附带说明,我知道 Laravel 7 中的 references()->on() 已更改,现在它可以与 constrained() 一起使用,但两种情况下的错误仍然相同。请帮我解决这个问题。

感谢和亲切的问候

【问题讨论】:

    标签: php mysql laravel laravel-7


    【解决方案1】:

    在您的终端中,运行:

    php artisan make:migration modify_best_answer_id_to_bigint_unsigned_not_null_to_questions_table
    --table=questions
    

    它为您创建了一个迁移文件来更改“best_answer_id”的数据类型。

    在迁移文件的 up() 方法中,使用 unsignedBigInterger('best_answer_id')->nullable()->change(); 更改 'best_answer_id';

    public function up()
    {
        Schema::table('questions', function (Blueprint $table) {
            $table->unsignedBigInteger('best_answer_id')->nullable()->change();
        });
    }
    

    然后,在终端中运行:

    php artisan make:migration add_foreign_best_answer_id_to_questions_table --table=questions
    

    然后,在此迁移文件中,将外部“best_answer_id”添加到问题表中:

    public function up()
    {
        Schema::table('questions', function (Blueprint $table) {
            $table->foreign('best_answer_id')
                  ->references('id')
                  ->on('answers')
                  ->onDelete('SET NULL');
        });
    }
    

    最后,运行:

    php artisan migrate
    

    它对我有用。 希望它对你有用!

    【讨论】:

      【解决方案2】:

      ->id()->bigInteger() 不是 ->integer() 它也没有签名。 由于列类型必须匹配才能具有外键约束,因此它应该是:

      $table->unsignedBigInteger('best_answer_id')->nullable();
      

      其中:

              $table->integer('best_answer_id')->nullable();
      

      【讨论】:

      • 所以 laravel 中默认的 ID 是 bigInteger?
      • 是的,正如您在laravel.com/docs/7.x/migrations中看到的那样
      • @Steal1702 是同样的错误吗?另请注意,我稍微更新了我的答案
      • 是的,我尝试了 unsignedBigInteger() 和 bigInteger()->unsigned() 但错误仍然相同,即 SQLSTATE[HY000]: General error: 1005 Can't create table laravel-qa.@ 987654328@ (errno: 150 "Foreign key constraint is wrongly forms") (SQL: alter table questions add constraint questions_best_answer_id_foreign foreign key (best_answer_id) references answers (id) on delete SET NULL)
      • 是的,它做到了。当我使用 $table->foreign('best_answer_id')->references('id') ->on('answers')->onDelete('SET NULL');我收到上述错误,但是当我使用 constrained() 而不是 references()->on() 时,我收到错误消息 SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax;检查与您的 MariaDB 服务器版本相对应的手册,以在第 1 行的删除 SET NULL' 附近使用正确的语法(SQL:更改表 questions 添加约束 questions_best_answer_id_foreign 外键(best_answer_id)引用 `` () 删除 SET NULL)
      猜你喜欢
      • 2017-10-03
      • 2019-07-25
      • 2017-10-04
      • 2018-02-19
      • 2021-05-26
      • 2019-11-02
      • 2023-03-19
      • 2020-04-15
      • 1970-01-01
      相关资源
      最近更新 更多