gpt4 book ai didi

php - Laravel 5.5 使用生产数据库整合迁移

转载 作者:可可西里 更新时间:2023-11-01 06:35:46 24 4
gpt4 key购买 nike

希望我能解释清楚。

我有一个已经投入生产的 Laravel 应用程序。所以,我有一堆有很多变化的迁移文件。我想在不丢失数据库的情况下整合这些迁移文件。

认为这会起作用的方式:

  1. 将所有生产表迁移到所需状态。
  2. 将所有迁移文件合并为所需的最少数量的文件。
  3. 清除迁移表。
  4. 运行迁移或填充迁移表。

我想这样做的部分原因是因为我想公开一些服务提供商,并尽可能提供最干净的迁移集。

困难的版本可能是:

  1. 备份或复制表格。
  2. 运行迁移。
  3. 编写并运行脚本来填充“干净”的表。

只是希望有比这更简单的方法。

编辑(来自评论):我有一个生产数据库,其中包含大约 50 多个迁移文件 - 一些小改动,一些大改动。如果我合并,所需的迁移数量大约为 12 次左右。我想合并迁移文件,但仍然能够在生产环境中执行 migrate:rollback - 但我不会这样做。

最佳答案

经过几次过度设计和过于聪明的解决方案尝试后,我认为以下是该问题的可行解决方案。

长话短说:

  • 从无到有构建架构的迁移两侧的书挡迁移。
  • 更新项目。
  • 迁移。
  • 删除书挡和所有以前的迁移。
  • migrations 表中删除记录。

第一个书挡重命名了受影响的表格。第二个书挡将数据从重命名的表复制到新表,然后删除重命名的表。

注意:您可以在书挡内做任何您想做的事情,这只是最低要求。

那么,假设您使用以下类似的迁移方式:

  • 2017_09_05_000000_create_some_table.php
  • 2017_09_05_000001_add_field_x_to_some_table.php
  • 2017_09_05_000002_add_field_y_to_some_table.php
  • 2017_09_05_000003_add_field_z_to_some_table.php

我们将创建另一个迁移:

  • 2017_09_05_000004_pre_refresh.php

我们将根据我们现有的知识创建另一个迁移:

  • 2017_09_05_000005_create_some_table.php

我们将创建最后一个书挡,其中将发生数据迁移:

  • 2017_09_05_000006_post_refresh.php

前四个迁移不会运行,因为它们已经运行过了。

/** 2017_09_05_000004_pre_refresh.php */
class PreRefresh extends Migration
{
public function up()
{
$prefix = 'zz_';
$tablesToRename = [
'foos',
'bars'
];

foreach($tablesToRename as $table) {
Schema::rename($table, $prefix . $table);
}
}
}

无需 Markdown ,因为这是一次性交易。这将首先运行,这将导致数组中列出的所有表都被重命名。然后合并(优化)迁移将运行。

/** 2017_09_05_000006_post_refresh.php */
class PostRefresh extends Migration
{
public function up()
{
// Do what you need to do.
// If you cannot use your models, just use DB::table() commands.

$foos = DB::table('zz_foos')->get();
foreach ($foos as $foo) {
DB::table('foo')->insert([
'id' => $foo->id,
'created_at' => $foo->created_at,
'updated_at' => $foo->updated_at
]);
}

$bars = DB::table('zz_bars')->get();
foreach ($bars as $bar) {
DB::table('bar')->insert([
'id' => $bar->id,
'created_at' => $bar->created_at,
'updated_at' => $bar->updated_at,
'foo_id' => $bar->foo_id
]);
}

// Tear down.
$prefix = 'zz_';
$tablesToRename = [
'foo',
'bar'
];

foreach ($tablesToRename as $table) {
DB::statement('SET FOREIGN_KEY_CHECKS=0');
Schema::dropIfExists($prefix . $table);
DB::statement('SET FOREIGN_KEY_CHECKS=1');
}
}
}

运行此命令后,您可以从 pre_refresh 和之前删除所有迁移。以及 post_refresh。然后您可以进入 migrations 表并删除这些迁移的条目。

删除条目并非完全必要,但如果您migrate:rollback,您将收到错误消息,指出无法找到迁移。

注意事项

  1. 如果架构在设计上不是模块化的,它可能会非常麻烦。但是,如果您将代码分离到服务中,这似乎会更容易一些。
  2. 迁移期间的 Laravel 错误处理和消息非常有限;因此,调试可能很困难。
  3. 强烈建议从您的应用/服务中最稳定的表开始。此外,从那些对您的应用来说是基础的开始也可能被证明是有益的。

注意:当我实际在生产中这样做时,不仅仅是我的本地(一遍又一遍),如果没有更好的答案,那么我会接受这个。

注意事项

如果您通过谨慎的迁移将您的应用程序分解为服务提供者,那么您可以在运行迁移时在 /config/app 中注释掉服务提供者。这样您就可以为现在的基线服务创建一个批处理。因此,假设您有以下迁移,其中每个字母代表一个迁移,每个重复的字母代表相同的服务:

  • 一个
  • B
  • C
  • 一个
  • C
  • B
  • 一个

合并服务 A 后:

  • B
  • C
  • C
  • B
  • 一个

合并B后:

  • C
  • C
  • 一个
  • B

合并C后:

  • 一个
  • B
  • C

更新

到目前为止,54 次迁移减少到 27 次。我什至从大型 up()down() 方法中提取了一些架构更改,并将它们分开迁移。这里好的副作用是批处理。我从支持其他所有内容的基表开始迁移;因此,回滚是一个服务接一个服务。

关于php - Laravel 5.5 使用生产数据库整合迁移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46056078/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com