Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第6章:Schema和版本迁移

第6章:Schema和版本迁移

自定义迁移 (Custom Migration)

何时需要自定义迁移

当数据模型发生以下复杂变更时,轻量级迁移无法满足需求,需使用自定义迁移:

  • 属性类型发生不兼容的变更(如String改为Int)
  • 需要执行数据清洗或转换逻辑(如拆分合并字段)
  • 涉及非标准关系调整(如一对多改为多对多)

实现自定义迁移的步骤

  1. 创建映射模型(Mapping Model)

    # 在Xcode中:
    File -> New -> File -> Mapping Model
    # 选择源版本和目标版本数据模型
    
  2. 编写迁移策略类

    class CustomMigrationPolicy: NSEntityMigrationPolicy {
        // 属性转换示例:将fullName拆分为firstName/lastName
        @objc func transformFullName(forInsertion: String) -> [String: String] {
            let components = forInsertion.components(separatedBy: " ")
            return ["firstName": components.first ?? "", 
                   "lastName": components.last ?? ""]
        }
    }
    
  3. 配置迁移选项

    let container = try ModelContainer(
        for: Book.self,
        migrationPlan: MyMigrationPlan.self,
        configurations: ModelConfiguration(
            migrationPlan: MyMigrationPlan.self
        )
    )
    

核心API与工具

工具/API用途
NSMigrationManager管理迁移过程的核心类
NSEntityMigrationPolicy实现自定义迁移逻辑的基类
NSMappingModel描述源模型与目标模型之间的映射关系
modelConfiguration配置迁移时使用的模型版本

调试迁移过程

  1. 启用详细日志:

    UserDefaults.standard.set(true, forKey: "com.apple.CoreData.SQLDebug")
    
  2. 常见错误处理:

    • 错误:"Can't find mapping model for migration"

      • 检查Mapping Model是否添加到编译目标
      • 验证源/目标模型版本选择是否正确
    • 错误:"Migration failed due to missing source instance"

      • 检查实体/属性名称拼写
      • 验证NSEntityMigrationPolicy的方法签名

最佳实践

  1. 分阶段迁移:对于大型变更,拆分为多个小版本逐步迁移
  2. 数据备份:迁移前确保有完整数据备份
  3. 测试策略:
    // 测试环境使用内存存储验证迁移
    let testContainer = ModelContainer(
        for: Schema([Book.self]), 
        configurations: ModelConfiguration(inMemory: true)
    )
    
  4. 性能优化:
    • 批量处理数据(每次迁移1000条左右记录)
    • 禁用UI更新直到迁移完成

完整示例:书籍出版日期格式迁移

// 旧模型:出版日期为String类型(格式:"YYYY-MM-DD")
// 新模型:出版日期为Date类型

class BookDateMigrationPolicy: NSEntityMigrationPolicy {
    private static let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()
    
    @objc func transformToDate(forInsertion: String) -> Date? {
        return Self.dateFormatter.date(from: forInsertion)
    }
}

注意:自定义迁移完成后,建议运行数据完整性检查,验证所有关键数据是否迁移成功。

Last Updated:: 5/30/25, 5:48 PM