add prod data migration schema preflight

This commit is contained in:
Prodiglagla
2026-06-14 12:46:49 +08:00
parent 40b1f722a3
commit 59b93e9f78
+51
View File
@@ -26,6 +26,23 @@ function Invoke-Postgres($Namespace, $Sql) {
kubectl -n $Namespace exec statefulset/postgres -- sh -lc "PGPASSWORD=\`$POSTGRES_PASSWORD psql -U postgres -d $Database -Atc '$escapedSql'"
}
function Get-TableColumns($Namespace, $TableName) {
$sql = "select column_name || '|' || udt_name || '|' || is_nullable || '|' || coalesce(column_default, '') from information_schema.columns where table_schema='public' and table_name='$TableName' order by ordinal_position"
$lines = @(Invoke-Postgres $Namespace $sql)
$columns = @()
foreach ($line in $lines) {
if (-not $line) { continue }
$parts = $line -split '\|', 4
$columns += [pscustomobject]@{
Name = $parts[0]
UdtName = $parts[1]
Nullable = $parts[2]
Default = if ($parts.Count -ge 4) { $parts[3] } else { '' }
}
}
return $columns
}
Write-Host "Compatible business tables planned for migration: $($tables.Count)"
Write-Host "Excluded tables: databasechangelog, databasechangeloglock, V3 runtime audit/outbox/maintenance derived tables."
@@ -36,6 +53,40 @@ $missingNew = $tables | Where-Object { $_ -notin $newTables }
if ($missingOld) { throw "Old namespace is missing expected tables: $($missingOld -join ', ')" }
if ($missingNew) { throw "New namespace is missing expected tables. Run ircs-prod core migrator first: $($missingNew -join ', ')" }
$schemaIssues = @()
foreach ($table in $tables) {
$oldColumns = @(Get-TableColumns $OldNamespace $table)
$newColumns = @(Get-TableColumns $NewNamespace $table)
$newByName = @{}
foreach ($column in $newColumns) {
$newByName[$column.Name] = $column
}
$oldByName = @{}
foreach ($column in $oldColumns) {
$oldByName[$column.Name] = $column
if (-not $newByName.ContainsKey($column.Name)) {
$schemaIssues += "${table}: old column '$($column.Name)' is missing in target"
continue
}
$target = $newByName[$column.Name]
if ($column.UdtName -ne $target.UdtName) {
$schemaIssues += "$table.$($column.Name): type mismatch old=$($column.UdtName) new=$($target.UdtName)"
}
}
foreach ($column in $newColumns) {
if (-not $oldByName.ContainsKey($column.Name) -and $column.Nullable -eq 'NO' -and -not $column.Default) {
$schemaIssues += "${table}: target required column '$($column.Name)' has no old value and no default"
}
}
}
if ($schemaIssues.Count -gt 0) {
$schemaIssues | ForEach-Object { Write-Host "SCHEMA ISSUE: $_" }
throw "Schema preflight failed with $($schemaIssues.Count) issue(s)."
}
Write-Host "Schema preflight passed for $($tables.Count) compatible business tables."
if (-not $Execute) {
Write-Host "Dry run only. Add -Execute to stream data from $OldNamespace to $NewNamespace."
exit 0