如何解决使用迁移工具时如何编写幂等迁移
考虑下面的两个迁移脚本。脚本由执行脚本的迁移工具运行,并在成功时插入 [dbo].[MigrationHistory]
以跟踪迁移历史。
(1)检查表是否存在
-- File: 0050-CreatePersonsTable.sql
-- Only check if the table exists; create if not.
IF NOT EXISTS (
SELECT TOP 1 *
FROM informatION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = 'Persons'
)
BEGIN
CREATE TABLE [dbo].[Persons] (
PersonID int,LastName varchar(255),FirstName varchar(255),Address varchar(255),City varchar(255)
)
END
(2)查看迁移历史表
-- File: 0050-CreatePersonsTable.sql
-- Check migration history table to see if '0050-CreatePersonsTable.sql'
-- was already applied
IF NOT EXISTS (
SELECT *
FROM [dbo].[MigrationHistory]
WHERE ScriptName = '0050-CreatePersonsTable.sql'
)
BEGIN
CREATE TABLE [dbo].[Persons] (
PersonID int,City varchar(255)
)
END
-- On success the migration tool inserts '0050-CreatePersonsTable.sql'
-- into the [dbo].[MigrationHistory] table.
问题:
IF NOT EXISTS (...)
谓词具有误导性。如果之前执行的迁移已经创建了表怎么办?然后将跳过此迁移,数据库将处于意外状态。现在为了解决这个问题,我可以添加一个额外的检查来查看表是否存在,然后执行一组不同的指令。这没问题,但是如果表存在并且预期的列存在但数据类型错误(例如,姓氏是 nvarchar)怎么办。现在我可以写另一个检查数据类型是否正确,如果不正确则修复它们。
这些谓词很快就会失控。
为什么不避免所有这些并只检查 [dbo].[MigrationHistory]
表?在这种情况下,迁移工具按顺序执行迁移。即 0001 到 0049 迁移在 0050-CreatePersonsTable.sql
之前运行。我期望在应用此迁移时数据库处于特定状态。如果 [dbo].[Persons]
表已经存在(无论出于何种原因),那么我希望迁移失败,因为数据库处于意外状态。
声明:第二次迁移是更好、更安全的迁移。
有什么我忽略的东西吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。