在创建新字段的迁移时,将数据从一个字段复制到另一个字段的最佳方法是什么?

问题描述 投票:3回答:4

我有一个数据库表,其字段具有布尔字段类型。现在,根据新要求,该字段应更改为小整数类型。

为了实现它,我创建了一个迁移并在同一个迁移文件中添加了脚本,以将值从旧字段复制到新字段。但是,我认为这不是我遵循的最佳方法。有人可以帮助并建议处理这种情况的最佳方法。

public function up()
{
    Schema::table('skills', function (Blueprint $table) {
        $table->tinyInteger('skill_type_id')->nullable()->comment = '1 for advisory skills, 2 for tools, 3 for language & framework';
    });
    $skill_object = (new \App\Model\Skill());
    $skills = $skill_object->get();
    if (_count($skills)) {
        foreach($skills as $skill) {
            $skill_type  = 1;
            if ($skill->is_tool) {
                $skill_type = 2;
            }
            $skill_object->whereId($skill->id)->update(['skill_type_id' => $skill_type]);
        }
    }
}
laravel model-view-controller database-migration
4个回答
1
投票

您可以使用02迁移来完成,第一个是创建新字段,就像已经做的那样。第二种是使用raw语句创建迁移,以将值从旧字段复制到新字段。如果您不再需要旧字段,则可以创建删除旧字段的第三个迁移。

public function up()
{
    Schema::table('skills', function (Blueprint $table) {
       DB::statement('UPDATE skills SET skill_type_id = IF(is_tool, 2, 1)');
    }
}

1
投票

您可以在方案中通过以下方式执行此操作(更新数据)。

  • 在迁移后创建单独的路由并更新数据。
  • 创建播种机(在迁移文件中具有与上面相同的查询)运行播种机。

但是,如果您尝试使用生产数据库执行此操作,则上述两种解决方案都没有什么风险。如果有人错误地点击了URL并多次运行播种机,那就很难管理。

我相信在修改模式后通过种子(修改)同一迁移文件上的数据来解决问题的最佳方法,因为迁移不会再次运行(甚至是错误的)迁移后。你正在按照我的想法采取正确的方式。


1
投票

您可以自由地开发自己的方式来完成此任务,但就迁移而言,这些是用于在团队之间控制和共享应用程序的数据库模式,而不是实际数据;)

  • 您可以为此任务创建单独的播种器。
  • 它将使您的迁移保持干净,并在需要时轻松回滚。

注意:不要在DatabaseSeeder中包含此播种器类。

这些播种器类仅用于在修复当前功能后更新现有数据(我考虑到,您已根据新要求修复了代码)。所以,没有必要担心重新运行相同的播种机类。


0
投票

考虑到(laracaststack-overflow),我会优先考虑上面提供的建议,因为我既不需要维护额外的路线也不需要额外的迁移(03)。

我可以在这里建议的唯一改进是你可以使用这样的数据库事务:

// create new column
DB::transaction(function () {
  update new column
  delete old column
});
© www.soinside.com 2019 - 2024. All rights reserved.