希望我能很好地解释这一点.
我有一个Laravel应用程序,已经生产了一分钟.所以,我有一堆迁移文件,有很多变化.我想整合这些迁移文件而不会丢失数据库.
我认为这会起作用的方式:
>将所有生产表迁移到所需状态.
>将所有迁移文件合并到所需的最少文件数中.
>清除迁移表.
>运行迁移或填充迁移表.
我想这样做的部分原因是因为我希望公开一些服务提供商,并尽可能使用最干净的迁移设置.
困难的版本可能是:
>备份或重复表.
>运行迁移.
>编写并运行脚本以填充“干净”表.
只是希望有一种比这更简单的方法.
编辑(来自评论):我有一个生产数据库,其中包含大约50个迁移文件 – 一些小的更改,一些大的更改.如果我合并,所需的迁移数量大约为12左右.我想整合迁移文件,但仍然能够执行迁移:生产回滚 – 不是我想要的.
TL;博士:
>迁移任何一方的Bookend迁移,无需构建模式.
>更新项目.
>迁移.
>删除书挡和所有以前的迁移.
>从迁移表中删除记录.
第一个书挡重命名受影响的表.第二个书挡将数据从重命名的表复制到新表,然后删除重命名的表.
注意:你可以在书挡内做任何你喜欢的事情,这只是最低限度.
那么,让我们说你的迁移如下:
> 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);
}
}
}
不需要下降,因为这是一次性交易.这将首先运行,这将导致重命名数组中列出的所有表.然后将运行合并(优化)迁移.
/** 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.然后,您可以进入迁移表并删除这些迁移的条目.
删除条目并不是完全必要的,但如果您迁移:rollback,您将收到错误消息,指出无法找到迁移.
注意事项
>如果架构不是模块化的,那么它可能非常麻烦.但是,如果您已将代码分离为服务,那么它似乎更容易一些.
>迁移过程中的Laravel错误处理和消息非常有限;所以,调试可能很困难.
>强烈建议从应用程序/服务中最稳定的表开始.此外,从您的应用程序的基础开始也可能是有益的.
注意:当我在生产中实际执行此操作时,不仅仅是我的本地(一遍又一遍),如果没有更好的答案,那么我会接受这一点.
注意事项
如果您通过谨慎的迁移将应用程序分解为服务提供商,则可以在运行迁移时在/ config / app中注释掉服务提供商.这样,您可以为现在基线的服务创建批处理.因此,假设您有以下迁移,其中每个字母代表一个迁移,每个重复的字母代表相同的服务:
> A.
> B.
> C.
> A.
> C.
> B.
> A.
合并服务A后:
> B.
> C.
> C.
> B.
> A.
合并B后:
> C.
> C.
> A.
> B.
合并C后:
> A.
> B.
> C.
更新
迄今已将54次迁移降至27次.我甚至从大型up()和down()方法中取出了一些Schema更改,并使它们成为单独的迁移.这里好的副作用是批次.我从基表开始迁移,其中支持其他所有内容;因此,回滚更多的是服务.