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

Adding column containing foreign key to existing table in production in Laravel

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

$table->unsignedBigInteger('campaign_id');

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

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

问题是当 运行ning php artisan migrate 时我得到一个错误 Cannot add a NOT NULL column with default value NULL。这似乎很公平,因为该列不可为空且没有默认值。但是使列可为空或设置默认值似乎并不可取。

现在我的 participants table 与 table visitorsone-to-one 关系,其中每个参与者都有一个访问者,但不是每个访问者都有一个参与者。 visitors table 与 table campaign 也有 many-to-one 关系。这意味着理论上我可以为参与者填充刚刚创建的 campaign_id,例如:

$participant->visitor->campaign->id

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

我通过将以下内容添加到 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();
    }
}