fix(models): isolate versioned migration sessions

This commit is contained in:
2026-07-22 14:45:41 +08:00
parent 78d4845688
commit 217f82c57c
2 changed files with 12 additions and 5 deletions

View File

@@ -33,14 +33,18 @@ func runVersionedMigrations(database *gorm.DB) error {
{version: 2, name: "deduplicate_project_tags", run: deduplicateLegacyProjectTags},
}
for _, migration := range migrations {
// Connection callbacks can provide an initialized Gorm session. Start each
// migration from a clean statement so Model/Where clauses used to check the
// version table are not inherited by the data-repair transaction.
migrationDatabase := database.Session(&gorm.Session{NewDB: true})
var applied int64
if err := database.Model(&SenlinAgentSchemaMigration{}).Where("version = ?", migration.version).Count(&applied).Error; err != nil {
if err := migrationDatabase.Model(&SenlinAgentSchemaMigration{}).Where("version = ?", migration.version).Count(&applied).Error; err != nil {
return err
}
if applied > 0 {
continue
}
if err := database.Transaction(func(tx *gorm.DB) error {
if err := migrationDatabase.Session(&gorm.Session{NewDB: true}).Transaction(func(tx *gorm.DB) error {
details, err := migration.run(tx)
if err != nil {
return err
@@ -61,7 +65,7 @@ func runVersionedMigrations(database *gorm.DB) error {
func normalizeLegacyProjectIdentifiers(tx *gorm.DB) (map[string]int, error) {
var projects []SenlinAgentProject
if err := tx.Select("id", "owner_id", "identifier").Order("owner_id asc, id asc").Find(&projects).Error; err != nil {
if err := tx.Model(&SenlinAgentProject{}).Select("id", "owner_id", "identifier").Order("owner_id asc, id asc").Find(&projects).Error; err != nil {
return nil, err
}
@@ -121,7 +125,7 @@ func uniqueIdentifier(base string, reserved map[string]struct{}) string {
func deduplicateLegacyProjectTags(tx *gorm.DB) (map[string]int, error) {
var tags []SenlinAgentTag
if err := tx.Select("id", "identity", "project_id", "name").Order("project_id asc, name asc, id asc").Find(&tags).Error; err != nil {
if err := tx.Model(&SenlinAgentTag{}).Select("id", "identity", "project_id", "name").Order("project_id asc, name asc, id asc").Find(&tags).Error; err != nil {
return nil, err
}
keepers := make(map[string]SenlinAgentTag)

View File

@@ -35,7 +35,10 @@ func TestAutoMigrateUpgradesLegacyProjectsAndTagsWithoutLosingAssociations(t *te
require.NoError(t, database.Exec(statement).Error)
}
require.NoError(t, AutoMigrate(database))
// PostgreSQL migrations run through database.Connection, whose callback DB can
// carry an initialized Gorm statement. Exercise that mode so model state from
// the migration-version lookup cannot leak into the data-repair transaction.
require.NoError(t, AutoMigrate(database.Session(&gorm.Session{Initialized: true})))
var projects []SenlinAgentProject
require.NoError(t, database.Order("id asc").Find(&projects).Error)