SwiftData轻量迁移问题:属性重命名后数据丢失并报错
SwiftData属性重命名轻量迁移修复方案
问题根源
你碰到的NSCocoaErrorDomain Code=134504报错,本质是误用了分段迁移(staged migration),导致系统无法识别旧数据库的schema版本,再加上轻量迁移配置不当,最终触发数据丢失。属性重命名属于轻量迁移范畴,完全不需要用分段迁移计划,直接通过schema版本标记和属性映射就能搞定。
修复步骤
1. 修正Schema版本定义
给V1和V2模型正确标记版本,V2里必须用@Attribute(originalName:)指定属性原名,让SwiftData能关联新旧字段:
// TripsSchemaV1.swift import SwiftData @Model final class TripV1 { var name: String // 其他原有属性 init(name: String) { self.name = name } } // TripsSchemaV2.swift import SwiftData @Model final class Trip { @Attribute(originalName: "name") var title: String // 其他属性和V1完全一致 init(title: String) { self.title = title } }
2. 删除错误的分段迁移计划
直接删掉你定义的TripsMigrationPlan,轻量迁移不需要这套逻辑,留着反而会干扰正常的版本识别。
3. 正确初始化ModelContainer
在App入口初始化容器时,指定包含新旧版本模型的schema范围,并开启自动迁移:
import SwiftUI import SwiftData @main struct TripsApp: App { var body: some Scene { WindowGroup { ContentView() } .modelContainer(for: Trip.self, configurations: ModelConfiguration( schema: Schema([TripV1.self, Trip.self]), isStoredInMemoryOnly: false, migrationOptions: .enableMigration )) } }
4. 验证迁移效果
- 测试前别删旧App,确保设备/模拟器上保留原有数据
- 启动App后看控制台有没有迁移成功的日志
- 进入App检查原有记录的
title字段是否正确继承了旧name的值
关键注意点
- 轻量迁移只适用于属性重命名、新增/删除可选属性这类简单变更,复杂结构变更才需要分段迁移
- 必须让Schema同时包含新旧版本的模型,SwiftData才能识别版本映射关系
- 如果之前误用分段迁移导致数据库损坏,得先删App重新部署,再按上述步骤测试迁移
内容的提问来源于stack exchange,提问作者azamsharp
相关产品推荐
相关产品推荐

