Azure DevOps YAML如何实现动态数量数据库的Flyway迁移更新
你描述的多数据库动态Flyway迁移流程完全可以通过Azure DevOps Pipelines原生能力实现,无需额外开发控制台应用,具体实现方案如下:
前置权限配置
首先需要给Pipeline对应的服务主体开通必要权限,保证流程能正常执行:
- 主数据库的只读查询权限,用于拉取所有待迁移的数据库标识列表
- Key Vault的机密读取权限,用于拉取对应数据库的完整连接字符串
- 开启Pipeline作业的
允许脚本访问OAuth令牌配置,支持跨阶段传递动态生成的变量
两阶段Pipeline实现逻辑
整个流程分为两个阶段执行,第一阶段生成待迁移的数据库列表,第二阶段并行执行所有数据库的Flyway迁移。
阶段1:动态生成待迁移数据库列表
该阶段仅执行1次,通过脚本查询主数据库获取所有需要做迁移的数据库标识,将结果序列化为JSON格式后输出为Pipeline跨阶段变量。
示例代码片段如下:
stages: - stage: GenerateDBList jobs: - job: QueryMainDB steps: # 建议先通过Azure Key Vault任务拉取主数据库的连接字符串,避免硬编码 - task: AzureKeyVault@2 inputs: azureSubscription: '你的Azure服务连接名称' KeyVaultName: '你的Key Vault名称' SecretsFilter: 'main-db-connection-string' RunAsPreJob: false - task: AzurePowerShell@5 name: OutputDBList inputs: azureSubscription: '你的Azure服务连接名称' ScriptType: 'InlineScript' Inline: | # 连接主数据库查询活跃的待迁移库标识 $mainConnStr = "$(main-db-connection-string)" $conn = New-Object System.Data.SqlClient.SqlConnection($mainConnStr) $conn.Open() $query = "SELECT db_unique_key, kv_conn_secret_name FROM tenant_db_list WHERE need_migrate = 1" $cmd = New-Object System.Data.SqlClient.SqlCommand($query, $conn) $reader = $cmd.ExecuteReader() $dbList = @() while ($reader.Read()) { $dbList += @{ dbKey = $reader["db_unique_key"].ToString() connSecretName = $reader["kv_conn_secret_name"].ToString() } } $conn.Close() # 序列化后输出为跨阶段变量 $dbListJson = $dbList | ConvertTo-Json -Compress Write-Host "##vso[task.setvariable variable=dbList;isOutput=true]$dbListJson"
阶段2:并行执行多库Flyway迁移
该阶段依赖阶段1的输出结果,通过YAML的each语法动态生成多个并行作业,每个作业对应一个数据库的迁移任务,直接复用你原有单库场景的Flyway执行逻辑即可。
示例代码片段如下:
- stage: BatchMigrateDB dependsOn: GenerateDBList # 绑定预先配置好的Key Vault变量组,可直接通过变量名读取机密 variables: - group: key-vault-secret-group jobs: # 遍历阶段1输出的数据库列表,动态生成作业 - ${{ each dbItem in stageDependencies.GenerateDBList.QueryMainDB.outputs['OutputDBList.dbList'] }}: - job: Migrate_${{ replace(dbItem.dbKey, '-', '_') }} displayName: 迁移数据库${{ dbItem.dbKey }} steps: - task: Bash@3 displayName: 调用Flyway CLI执行迁移 inputs: targetType: 'inline' script: | # 从变量组获取当前库的连接字符串,替换为你实际的Flyway参数 flyway migrate \ -url="$(${{ dbItem.connSecretName }})" \ -user="$(common-db-user)" \ -password="$(common-db-password)" \ -locations="filesystem:./sql/migrations" \ -configFiles="./flyway.conf"
方案对比优势
相比自行开发控制台应用的方案,原生YAML实现有以下优势:
- 无需维护额外的应用代码,降低开发和迭代成本,可直接复用已有的Flyway配置和迁移脚本
- 多数据库迁移作业并行执行,迁移效率远高于单进程循环调用,数据库数量越多优势越明显
- 每个数据库的迁移日志独立存储,单个库迁移失败不会影响其他库,还支持单独重试失败的迁移作业
- 可直接对接Azure DevOps的审批、通知、告警等原生能力,不需要额外做集成
补充说明:如果你的待迁移数据库数量超过Azure DevOps单阶段并行作业上限,可在阶段1输出列表时做分批处理,分多个批次执行迁移即可。
内容的提问来源于stack exchange,提问作者Water
相关产品推荐
相关产品推荐

