加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

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

发布时间:2020-12-11 23:36:23 所属栏目:MySql教程 来源:网络整理
导读:希望我能很好地解释这一点. 我有一个Laravel应用程序,已经生产了一分钟.所以,我有一堆迁移文件,有很多变化.我想整合这些迁移文件而不会丢失数据库. 我认为这会起作用的方式: 将所有生产表迁移到所需状态. 将所有迁移文件合并到所需的最少文件数中. 清除迁移

希望我能很好地解释这一点.

我有一个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更改,并使它们成为单独的迁移.这里好的副作用是批次.我从基表开始迁移,其中支持其他所有内容;因此,回滚更多的是服务.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读