【问题标题】:How to force FluentMigrator to run migration even if DB version matches即使数据库版本匹配,如何强制 FluentMigrator 运行迁移
【发布时间】:2020-04-01 22:05:33
【问题描述】:

我也使用 FluentMigrator 3.2.1 和 dotnet-fm 来运行迁移。 想象一下,我有数据库版本 1,2,3,4 等等,类都标有

[FluentMigrator.Migration(1, "1")]
 [FluentMigrator.Migration(2, "2")]
 [FluentMigrator.Migration(3, "3")]
 [FluentMigrator.Migration(4, "4")]

并且它们都覆盖了 Up() 和 Down() 方法。 在开发环境中,我有数据库版本 4。我用新版本的存储过程修改“向上”脚本。数据库在 VersionInfo 表中已经有版本 4,我执行这个命令

dotnet-fm migrate -p Postgres -c "Server=192.168...server info" -a "/mnt/d/src/........DB.dll" up

我希望迁移器再次“强制”更新到版本 4,但看起来是看到数据库的版本已经是 4。 我用回滚到3和前滚到最新,但不方便,不适合CI/CD。 是否有任何优雅的方式来“强制”“向上”迁移,f.ex。带有迁移标签?

【问题讨论】:

    标签: postgresql migration database-migration fluent-migrator


    【解决方案1】:

    我是FluentMigrator 的共同维护者之一。这不是框架支持的东西,但有一种解决方法以及一种思考如何构建构建过程的方法。

    解决方法

    psql

    最简单的解决方法是使用psql 删除最新的迁移:

    psql -U username -h 192.160.128.101 -d mydatabase -c 'DELETE FROM VersionInfo WHERE Id = 4'
    

    psql 的 bash 包装器

    您可以使用bash 并为此命令创建一个函数。注意,你必须创建一个函数if you want to make this command accept a parameter。

    fm-rm()
    {
      # THIS DOES NO ERROR CHECKING.
      # DO NOT RUN THIS AGAINST A PRODUCTION SERVER.
      psql -U username -h $1 -d $2 -c 'DELETE FROM VersionInfo WHERE Id = $3'
    }
    

    然后你可以这样做:

    fm-rm localhost MyDatabase 4
    

    FluentMigrator 的 powershell 扩展

    此外,如果您使用 PowerShell,您可以编写类似的脚本并使用 PowerShell 强大的自动完成功能来加快输入速度。最近有人启动了一个 VisualStudio PowerShell 项目来做这样的事情,但它还不是很健壮。见:https://github.com/crimcol/FluentMigrator.VStudio你会写Rollback-FluentDatabase 4

    最佳实践

    如果您在开发环境中运行这些迁移,那么您需要的是创建测试数据库然后针对该测试数据库运行迁移的工作流。

    从您在示例中提供的命令行参数看来,您使用的是非 Windows 环境并使用 PostgreSql。我想为其添加示例的另一种解决方案是TestEnvironment.Docker,并通过 docker 启动 SQL Server 容器。 (不幸的是,SqlLocalDb 在 Linux 上不可用,而您正在使用 PostgreSql。在 Windows 上,SqlLocalDb 将是启动测试服务器和测试数据库的理想轻量级解决方案。)

    如果您使用的是 MSBuild,您还可以定义一个 TestSetup 目标来设置 DatabaseName_UnitTest 数据库。当我这样做时,我有一个基线 CreateSchema.sql 运行,创建一个数据库和一个时间点的模式,然后我应用所有迁移。通过这种方式,我可以保证发布过程应该有效,特别是如果我使用的是类似 GitFlow 的发布模型,我只在 master 分支之外部署。

    【讨论】:

    • 约翰,非常感谢您的回答。作为解决方案草案,我添加了额外的 FluentMigrator.Migrator 后代类,其中包含公共覆盖 void Up() 和 Execute.EmbeddedScript("name_of_latest_migration_script.sql");并且该类配备了[Tags("ForceExecLatestScript")]。因此,此迁移可以作为执行 dotnet-fm .... -up 之后的第二步执行,但要指定 --tag ForceExecLatestScript。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    相关资源
    最近更新 更多