为了账号安全,请及时绑定邮箱和手机立即绑定

通过“重置”到当前架构来修复损坏的迁移

通过“重置”到当前架构来修复损坏的迁移

PHP
Qyouu 2022-10-14 15:59:10
我们已经接管了一个旧的(3 年)Symfony 3.3 项目,使用教义迁移 1.0 包来处理迁移。不幸的是,迁移脚本已经被破坏了一段时间,没有人注意到,所以你不能在不检查现有数据库的情况下从源代码重新构建。我想解决这种情况,以便运行composer doctrine:migrate基本上只是运行一个虚拟脚本,该脚本创建当前模式的样子。我将如何做到这一点,以便在现有模式上运行它时不会中断?我想我会按照这些思路做一些事情:检查一个干净的项目(带有错误的旧迁移)获取生产数据库转储将生产数据库模式转储到 SQL 文件删除旧的迁移创建一个版本号与错误迁移中的“当前”/最高版本号相同的迁移文件运行迁移作为最后一步,通过删除数据库、导入生产数据库转储然后运行migrate来验证这是否确实有效,以验证没有任何中断。我只是不确定如何在 Doctrine 包的上下文中执行此操作(我是 PHP 新手),即使在查阅了文档之后(似乎并未涵盖这种情况)。
查看完整描述

1 回答

?
湖上湖

TA贡献2003条经验 获得超2个赞

我做的和我上面勾勒的完全一样,而且效果很好。对于上下文,我有一组用于迁移脚本的元数据:


"SELECT * FROM migration_versions" 

┌────────────────┐

│    version     │

├────────────────┤

│ 20161112122228 │

│ 20161113143631 │

│ 20161122223420 │

│ 20161124162611 │

│ 20161128151448 │

│ 20161207194257 │

│ 20161208114104 │

│ 20161208114105 │

│ 20170123074229 │

│ 20170125081729 │

│ 20170130080734 │

│ 20170130080820 │

│ 20170131082751 │

│ 20170201074705 │

│ 20170208092040 │

│ 20170208092917 │

│ 20170208103930 │

│ 20170608042313 │

│ 20170628044258 │

│ 20170930061118 │

└────────────────┘

这意味着我还会有一组相应的文件app/DoctrineMigrations/,称为app/DoctrineMigrations/Version20170930061118.php. 只有最后一个文件以实际内容结束,其余的将是空的假人。


我的更改的 Git 日志

创建一个虚拟模板来替换现有迁移的内容


在某些时候,现有的迁移已经停止工作。这是在 2020 年 3 月 1 日左右发现的。


这意味着不可能从新的源代码开始开发,使用教义:迁移:迁移命令,因为它很早就失败了。


同时,现有数据库包含有关过去执行了哪些迁移的元数据,因此任何修复都需要向迁移包发出信号,表明这些迁移已经/已经执行。


建议的解决方法是创建简单的“标记类”,它只是满足发出迁移已经完成/存在的信号的需要,然后用一个脚本替换最后一个迁移类的内容,该脚本只是创建一个与当前状态匹配的模式生产数据库是。


这是第 1 步。


将所有迁移脚本内容替换为空内容


这是修复中的第 2 步。基本上为 app/DoctrineMigrations/*.php 中的每个文件执行一个循环,并用虚拟模板替换它。这是完整的脚本


$ git show 773ccebee20425d7025152b338282f0a0034556f:app/DoctrineMigrations/create-dummy-migrations.sh

#!/bin/bash


for file in Version*.php; do 

    CLASS=$(basename $file .php)

    sed -e "s/CLASSNAME/$CLASS/" template.php > $file

done

这是完整的模板


git show 773ccebee20425d7025152b338282f0a0034556f:app/DoctrineMigrations/template.php

<?php


namespace Application\Migrations;


use Doctrine\DBAL\Migrations\AbstractMigration;

use Doctrine\DBAL\Schema\Schema;


/**

 * Dummy migration to fix faulty migration scripts issue 

 * discovered in March 2020.

 */

class CLASSNAME extends AbstractMigration

{

    /**

     * @param Schema $schema

     */

    public function up(Schema $schema)

    {

         $this->addSql('COMMENT ON table migration_versions IS \'migrations from 2016-2017 are stubs\'');

    }


    /**

     * @param Schema $schema

     */

    public function down(Schema $schema)

    {

    }

}

删除助手


从 prod 转储模式


使用脚本清理架构


grep -v -- '--' production-schema-2020.sql \ 

  | awk 1 ORS=' ' \

  | sed -r -e 's/;\s+/; /g' > cleaned.sql

从 SQL 脚本生成 Doctrine PHP 语句


脚本:sed -e "s/^(.*);/\$this->addSql('\1');/" cleaned.sql > cleaned-sql-to-php-statements.txt


将模式语句移动到上次迁移 中基本上将内容从复制粘贴cleaned-sql-to-php-statements.txt到


删除临时文件


对生成的 PHP SQL 语句的小调整和清理


查看完整回答
反对 回复 2022-10-14
  • 1 回答
  • 0 关注
  • 84 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信