【问题标题】:Adding column containing foreign key to existing table in production in Laravel将包含外键的列添加到 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

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

【问题讨论】:

标签: php laravel database laravel-artisan migrate


【解决方案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?
  • 这是业务需求,而不是数据库需求。是的,您需要定义外键或者它只是一个列。
  • 外键不可为空有缺点吗?
  • 不,只是没有必要。您在代码中定义业务规则,例如请求验证以确保关系存在。
猜你喜欢
  • 2018-02-27
  • 1970-01-01
  • 2020-04-14
  • 2017-12-07
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
  • 2012-04-19
相关资源
最近更新 更多