将包含外键的列添加到 Laravel 生产中的现有表中

Posted

技术标签:

【中文标题】将包含外键的列添加到 Laravel 生产中的现有表中【英文标题】:Adding column containing foreign key to existing table in production in Laravel 【发布时间】:2021-12-25 02:21:27 【问题描述】:

我有一个表participant,它与表campaignmany-to-one 关系。现在由于一些愚蠢的原因,我忘记添加一个列campaign_id,它包含表campaign 中行的外键。现在要解决这个问题,我可以轻松地将以下行添加到 create_participants_table 迁移文件并运行 php artisan migrate:fresh 命令,这将删除所有表并使用正确的列重新创建它们。

$table->unsignedBigInteger('campaign_id');

但问题是这两个表都已经投入生产并且已经包含数据,因此运行migrate:fresh 并不是最佳选择。所以在这种情况下,我会创建另一个名为 add_campaign_id_to_participants 的迁移文件,如下所示:

public function up()

    Schema::table('participants', function (Blueprint $table) 
        $table->unsignedBigInteger('campaign_id');
    );

问题是在运行php artisan migrate 时出现错误Cannot add a NOT NULL column with default value NULL。这似乎是公平的,因为该列不可为空并且没有默认值。但是使列可以为空或设置默认值似乎并不可取。

现在我的participants 表与visitors 表有one-to-one 关系,其中每个参与者都有一个访问者,但不是每个访问者都有一个参与者。同样visitors 表与campaign 表有many-to-one 关系。这意味着理论上我可以为参与者填写刚刚创建的campaign_id,如下所示:

$participant->visitor->campaign->id

现在我的问题是这是否可行,如果可以,我将如何实现?

【问题讨论】:

尝试`$table->unsignedBigInteger('campaign_id')->nullable();` 或`$table->unsignedBigInteger('campaign_id')->default(0);`。 laravel.com/docs/8.x/migrations#column-modifiers 我认为你没有理解@OlehTytarenko 的问题。 【参考方案1】:

我通过将以下内容添加到 add_campaign_id_to_participants 迁移文件来修复它。

public function up()

    Schema::table('participants', function (Blueprint $table) 
        $table->unsignedBigInteger('campaign_id')->default(0);
    );
    $participants = Participant::all();
    foreach($participants as $participant)
    
        $participant->campaign_id = $participant->visitor->campaign_id;
        $participant->save();
    

【讨论】:

您刚刚添加了一个普通列,而不是外键。在外键列中有空值没有错;这只是意味着没有关系。 是的,但就我而言,需要建立关系。每个参与者都需要有一个链接的活动。但是你的意思是我需要使用foreign而不是unsignedBigInteger? 这是业务需求,而不是数据库需求。是的,您需要定义外键或者它只是一个列。 外键不可为空有缺点吗? 不,只是没有必要。您在代码中定义业务规则,例如请求验证以确保关系存在。

以上是关于将包含外键的列添加到 Laravel 生产中的现有表中的主要内容,如果未能解决你的问题,请参考以下文章

使用 Alter Table 和现有 MYSQL 数据库添加外键时出现问题 - 无法添加!帮助!

如何将具有外键的列修改为 null?

rails 迁移更改了不相关的列

Laravel Eloquent 播种机计算每个外键的行数

Laravel 与复合外键的关系

删除包含外键的字段,而不删除该字段包含LARAVEL的所有项目