Laravel 5.5 将迁移与生产数据库合并

2024-02-24

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

我有一个 Laravel 应用程序,已经投入生产了一分钟。所以,我有一堆包含很多更改的迁移文件。我想合并这些迁移文件而不丢失数据库。

我的方式think这会起作用:

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

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

困难的版本可能是:

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

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

编辑(来自评论):我有一个生产数据库,其中包含大约 50 多个迁移文件 - 一些小的更改,一些大的更改。如果我合并的话,需要的迁移数量大约是 12 次左右。我想整合迁移文件,但仍然能够执行migrate:rollback关于生产——我不会。


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

tl;dr:

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

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

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

因此,假设您的迁移类似于以下内容:

  • 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。然后你可以进入migrations表并删除这些迁移的条目。

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

Caveats

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

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

注意事项

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

  • A
  • B
  • C
  • A
  • C
  • B
  • A

合并服务A后:

  • B
  • C
  • C
  • B
  • A

合并B后:

  • C
  • C
  • A
  • B

合并后C:

  • A
  • B
  • C

update

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Laravel 5.5 将迁移与生产数据库合并 的相关文章

  • 在 Laravel 中的编辑表单上获取选定选项

    我的网站订单有一个可编辑的表单 并且有以下字段 User quantity note status 我在此表单中还有其他选项 但只有这些字段对我来说很重要 以便能够获取默认值 例如 我希望能够查看用户默认订购的数量 然后我可以更改它或保留它
  • 如何删除 MySQL 数据库?

    你可能从我的上一个问题中注意到一个问题引发了更多的问题 在 MySQL 监视器中阅读 MySQL 手册 https stackoverflow com questions 1081399 我的数据库现在无法使用 部分原因是我想破坏东西并且无
  • div 中的文本字符有限,添加“阅读更多”链接并在单击链接时显示所有字符

    我有一个 div 里面有文本 使用 PHP 和 MySQL 显示 结构如下 div class description p Here is a lot of text p div 我想在 p 标签内的文本超过 100 个字符时显示 阅读更多
  • 从 php 到 JavaScript 的数组

    我正在尝试使用 json 将数组列表从 php 传输到 javascript 但它不起作用 JS ajax url getProfilePhotos php type post post or get method data if you
  • Mysql带限制的删除语句

    我试图从表中删除行 但出现错误 DELETE FROM chat messages ORDER BY timestamp DESC LIMIT 20 50 我在 50 时收到此错误 您的 SQL 语法有错误 检查与您的 MySQL 服务器版
  • 将IP保存到数据库中

    当用户登录时 我想将他们的 IP 保存在数据库中 我该怎么做呢 MySQL 字段最适合使用哪种类型 获取IP的PHP代码是什么样的 我正在考虑将其用作登录 会话内容的额外安全功能 我正在考虑使用用户现在拥有的 IP 检查用户从数据库登录的
  • MySql 视图脚本中的注释

    可以这样做吗 我尝试过多个 gui mysql workbench navicat toad for mysql 但没有一个保存这样的注释 something important select something else importan
  • json_encode 返回 NULL?

    由于某种原因 项目 描述 返回NULL使用以下代码 这是我的数据库的架构 CREATE TABLE staff id int 11 NOT NULL AUTO INCREMENT name longtext COLL
  • 如果用户在 Laravel 中经过身份验证,如何检查 Vue 组件?

    正如标题所述 我有点困惑如何根据用户是否登录并使用 Laravel 的 Auth 外观进行身份验证 使用 if else 语句处理 Vue 组件中的方法 我正在发出各种 Axios 请求 我需要根据用户是否登录来允许 禁止这些请求 我有 V
  • MySQL“列计数与第 1 行的值计数不匹配”是什么意思

    这是我收到的消息 ER WRONG VALUE COUNT ON ROW 列计数与第 1 行的值计数不匹配 这是我的全部代码 我的错误在哪里 DROP TABLE student CREATE TABLE employee emp id I
  • 使(文本到图像)图像具有一定的宽度但无限的长度?

    我有下面的代码 可以用大量文本生成图像 我希望该图像的宽度为 700 像素 我还希望它保留字符串所具有的段落结构 该字符串来自 MySQL 数据库 我怎样才能实现这一点 font 2 width imagefontwidth font st
  • 扩展构建器中的“映射到现有表”显示 TYPO3 中的奇怪问题

    在我的扩展中MyExt 我映射了模型Page to pagesTYPO3 中的表 首先它向我展示了type mismatch错误 无论如何我继续保存它 会发生以下情况 我的页面树变成这样 我的新记录表单仅显示 UID 而不显示标题 My P
  • ACL授权失败后ZF3重定向

    我有一个带有 ACL 的新 ZF3 应用程序 现在 我需要在未经授权的访问的情况下重定向到错误页面 例如 403 我认为最好的方法是触发一个事件 然后捕获它 但我失败了 全部都在我的用户模块中Module php 摘录 namespace
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • 休眠以持久保存日期

    有没有办法告诉 Hibernate java util Date 应该持久保存 我需要这个来解决 MySQL 中缺少的毫秒分辨率问题 您能想到这种方法有什么缺点吗 您可以自己创建字段long 或者使用自定义的UserType 实施后User
  • 使用 ImageMagick (PHP) 将 2 个图像并排合并为 1 个图像

    我认为这是一件容易的事 我有 2 张图片 JPG 我希望它们合并成一张图片 其中 2 张图片并排 所以我有图片 A 和图片 B 我想要图片 AB 并排 两个图像具有相同的宽度和高度 在本例中 宽度 200px 高度 300px 但是第二个图
  • Readfile 从大文件中读取 0 字节?

    我正在尝试通过以下方式发送一个大文件readfile 但是 没有任何内容发送到浏览器 并且readfile 回报0 not false 我尝试发送的文件大小为 4GiB 并且可由 PHP 读取 我正在设置set time limit 0 以
  • rake db 问题:迁移 -

    我无法为 Ruby on Rails 设置 MySQL 数据库 设置数据库并确保 config database yml 文件匹配后 我遇到了以下错误消息 U Rails alpha gt rake db migrate trace in
  • 通过 Sparkpost 发送 iCal 邀请

    我正在尝试使用 SparkPost 通过电子邮件以附件形式发送日历邀请 但收到电子邮件后邀请不会打开 我使用两个文件 calendarinvite php 来创建邀请 使用 Sendemail php 来发送电子邮件 calendarinv
  • 如何将变量插入 PHP 数组?

    我在网上查了一些答案 但都不是很准确 我希望能够做到这一点 id result id info array id Example echo info 0 这有可能吗 您需要的是 不推荐 info array id Example varia

随机推荐

  • 在 Node.js 中通过 ejs 使用 AJAX

    我想弄清楚如何在node js中使用ajax 我现在有这个 我如何在我的内部显示例如 order 0 name 和 order 1 name div id champ 当我按下名为 Press 的按钮时 app js var express
  • Internet Explorer 中的 RGBa

    我知道IE不支持RGBa 我还知道您可以使用以下方法 For IE 5 5 7 filter progid DXImageTransform Microsoft gradient startColorstr 99000000 endColo
  • 检查输入字段是否在普通 JavaScript 中具有焦点

    使用 jQuery 我可以测试输入字段是否具有焦点 如下所示 if is focus 不使用 jQuery 如何做到这一点 这个问题在这里得到了回答 Javascript 检测输入是否获得焦点 https stackoverflow com
  • tomcat无法建立ssl连接

    我无法与 tomcat 建立 ssl 连接 Chrome 写道 107 net ERR SSL PROTOCOL ERROR 我已经通过 keytool 生成了 mystore 文件 gt keytool genkey alias tomc
  • 使用PySpark以本地模式读取文件时出现OutOfMemoryError

    我有大约十几个 gpg 加密文件 其中包含我想使用 PySpark 分析的数据 我的策略是将解密函数作为平面映射应用到每个文件 然后在记录级别进行处理 def read fun generator filename with gpg ope
  • Android 风格签名未按预期工作

    我需要使用特定的签名配置来签署产品风格 我在 stackoverflow 上找到了一些参考资料 例如this https stackoverflow com questions 30898611 gradle signing flavors
  • MAC从shell脚本写入桌面

    有没有办法从 BASH 脚本向 MAC 桌面显示消息 我正在编写一个终端窗口脚本 需要在 MAC 桌面上显示一条消息 另外 如果这是从 BASH 脚本打开消息框的一种方法 Dennis 像这样 bin bash osascript e Te
  • 使用 thrift json 序列化将对象转换为 JSON 字符串

    我是储蓄新手 我需要将我的数据对象转换为JSON string with Thrift JSON序列化 我用这种方式尝试过 TSerializer serializer new TSerializer new TSimpleJSONProt
  • jQuery 方法:.submit() 与 .trigger('submit') 之间的区别

    jQuery 允许通过以下任一方式以编程方式触发表单提交 js form class hook submit js form class hook trigger submit 注 我的理解是 trigger submit is to su
  • C# == 运算符详细做什么?

    在 C 中 当您在两个对象上使用 运算符进行比较时 后台到底发生了什么 它只是比较地址吗 或者是类似 Equals 或 CompareTo 的东西吗 PS java中的 运算符怎么样 它的行为相同吗 据我所知 它按值 相等 比较值类型 它通
  • Clojure:如何在运行时找出函数的数量?

    给定一个函数对象或名称 我如何确定它的数量 就像是 arity func name 我希望有办法 因为 arity 在 Clojure 中非常重要 函数的元数存储在变量的元数据中 arglists meta str x x ys 这要求该函
  • Lisp 中的函数名可以有别名吗?

    就像包裹一样 我使用Emacs 也许 它可以提供某种解决方案 例如 defun the very very long but good name 稍后在代码中没有用处 但名字就像Fn 15或者第一个字母缩写也没有用 是否可以使用类似于包的别
  • Java 静态方法上的线程锁

    根据我对 Java 类的了解 非静态同步方法 在特定对象上获取锁 静态同步方法 在类上获取锁 我对此有点困惑 因为我们可以通过类名或对象名调用静态方法 请假设我的类有 4 个方法都是同步的 2 个方法是静态的 2 个方法不是静态的 如果我创
  • Jquery 在 Href 上创建双击事件

    伙计们是否可以使用 jquery 为 a href 创建双击事件 双击锚点执行操作的问题是 页面将在第一次单击时重定向 从而阻止双击及时响应 如果您想 拦截 点击事件 以便双击事件有机会在页面重定向之前触发 那么您可能必须设置点击超时 如下
  • 如何在 Django 中获取用户 IP 地址?

    如何在 Django 中获取用户的 IP 我有这样的看法 Create your views from django contrib gis utils import GeoIP from django template import Re
  • 如何在 Aurelia 中“继承”可绑定属性?

    我正在使用 TypeScript 开发 Aurelia 应用程序 在此应用程序中 我定义了一组自定义元素 每个元素共享一组可绑定属性 这些属性被转换为 css 设置 如以下简化示例所示 import computedFrom bindabl
  • 在 Azure Linux VM 中,什么仍然存在?什么磁盘收费?

    我在 Microsoft 的 Azure 中创建了一个小型 Linux VM 我还创建了一个 20GB BLOB 并将其安装为文件系统 在我的虚拟机上 我看到以下内容 根文件系统 约28GB 启动文件系统 约500MB 我的 20GB 文件
  • iphone AVEditDemo 或任何视频处理示例

    我正在尝试以某种方式处理视频 剪切和合并视频 录制屏幕并从该录制内容中制作视频 我也在互联网和 stackoverflow 上查找 看到苹果有一个名为 AVEditDemo 的代码示例 但我永远找不到它 如果有人有这个例子并愿意与我分享 或
  • 微软 Roslyn 与 CodeDom

    From a 新闻稿 http www infoworld com d application development microsofts roslyn reinventing the compiler we know it 176671
  • Laravel 5.5 将迁移与生产数据库合并

    希望我能很好地解释这一点 我有一个 Laravel 应用程序 已经投入生产了一分钟 所以 我有一堆包含很多更改的迁移文件 我想合并这些迁移文件而不丢失数据库 我的方式think这会起作用 将所有生产表迁移到所需状态 将所有迁移文件合并为所需