【问题标题】:Why state_id field is not create in regions table definition?为什么在区域表定义中未创建 state_id 字段?
【发布时间】:2021-12-10 06:19:30
【问题描述】:

我尝试将旧数据库从 laravel 5.x 重构为 laravel 8 并拥有 2 个相关表: 数据库/迁移/2019_05_21_144910_create_states_table.php:

<?php

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

class CreateStatesTable extends Migration {

   /**
    * Run the migrations.
    *
    * @return void
    */
   public function up()
   {
      Schema::create('states', function(Blueprint $table)
      {
            $table->smallIncrements('id')->unsigned();
            $table->string('code', 3)->unique();
         $table->string('name', 50)->unique();
         $table->string('slug', 55)->unique();
            $table->enum('active', ['A', 'I'])->default('I')->comment(' A=>Active, I=>Inactive');
         $table->index(['active','code'], 'fk_states_active_code_ixd');
         $table->index(['active','slug'], 'fk_states_active_slug_ixd');
      });
   }


   /**
    * Reverse the migrations.
    *
    * @return void
    */
   public function down()
   {
      Schema::drop('states');
   }

}

和数据库/迁移/2019_05_21_145001_create_regions_table.php:

<?php

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

class CreateRegionsTable extends Migration
{

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('regions', function (Blueprint $table) {

            $table->smallIncrements('id')->unsigned();

            $table->foreign('state_id')->references('id')->on('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');


            $table->string('name', 50);
            $table->string('slug', 55)->unique();

            $table->enum('active', ['A', 'I'])->default('I')->comment(' A=>Active, I=>Inactive');

            $table->unique(['state_id', 'name']);

            $table->index(['state_id', 'active'], 'fk_regions_state_id_active_ixd');
        });
    }


    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('regions');
    }

}

运行迁移命令时出错:

php artisan migrate:fresh --seed
...
Migrating: 2019_05_21_144910_create_states_table
Migrated:  2019_05_21_144910_create_states_table (626.91ms)
Migrating: 2019_05_21_145001_create_regions_table

   Illuminate\Database\QueryException 

  SQLSTATE[42000]: Syntax error or access violation: 1072 Key column 'state_id' doesn't exist in table (SQL: alter table `regions` add constraint `regions_state_id_foreign` foreign key (`state_id`) references `states` (`id`) on delete RESTRICT on update RESTRICT)

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:703
    699▕         // If an exception occurs when attempting to run a query, we'll format the error
    700▕         // message to include the bindings with SQL, which will make this exception a
    701▕         // lot more helpful to the developer instead of just the database's errors.
    702▕         catch (Exception $e) {
  ➜ 703▕             throw new QueryException(
    704▕                 $query, $this->prepareBindings($bindings), $e
    705▕             );
    706▕         }
    707▕     }

      +9 vendor frames 
  10  database/migrations/2019_05_21_145001_create_regions_table.php:31
      Illuminate\Support\Facades\Facade::__callStatic()

      +32 vendor frames 
  43  artisan:37
      Illuminate\Foundation\Console\Kernel::handle()

在区域表中,我有区域表,但没有 state_id 字段。看起来像线

$table->foreign('state_id')->references('id')->on('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');

被忽略了,我无法理解为什么?试了好几次...

更新 2: 我将 CreateRegionsTable 修改为:

Schema::create('regions', function (Blueprint $table) {

    $table->smallIncrements('id')->unsigned();
   $table->foreignId('state_id')->constrained('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');

但我遇到了其他错误:

  SQLSTATE[HY000]: General error: 3780 Referencing column 'state_id' and referenced column 'id' in foreign key constraint 'regions_state_id_foreign' are incompatible. (SQL: alter table `regions` add constraint `regions_state_id_foreign` foreign key (`state_id`) references `states` (`id`) on delete RESTRICT on update RESTRICT)

在 database/migrations/2019_05_21_144910_create_states_table.php 我有:

Schema::create('states', function(Blueprint $table)
{
    $table->smallIncrements('id')->unsigned();

我认为 foreignId 与 smallIncrements 不兼容...但哪种方法有效?

提前致谢!

【问题讨论】:

  • foreign 在现有列上添加约束。使用foreignId('state_id')-&gt;constrained() 创建列和外键索引。更多内容请关注docs

标签: laravel laravel-migrations


【解决方案1】:

$table-&gt;foreign() 方法仅将外键约束添加到现有列。你要找的方法是$table-&gt;foreignId()

所以而不是

$table->foreign('state_id')->references('id')->on('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');

在您的区域表迁移中,您应该这样做

$table->foreignId('state_id')->constrained('states')->onUpdate('RESTRICT')->onDelete('RESTRICT');

documentation

【讨论】:

  • 请看更新2
  • 抱歉回复晚了。 $table-&gt;foreignId('state_id') 方法默认添加一个 bigInteger 数据类型列,而 $table-&gt;smallIncrements() 添加一个 smallInteger 数据类型列。您不能将外键约束添加到两个不同的数据类型列。您可以将 states 表的 id 列更改为 bigIncrements() 或在您的区域表中,首先为 state_id 创建一个 smallInteger() 列,然后为其添加外键约束。
  • 请注意 smallInteger 列的最大限制为 32,767。所以使用 bigIntegers 更安全
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-20
  • 2020-04-02
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
  • 2018-03-04
  • 1970-01-01
相关资源
最近更新 更多