Hi I am trying to figure out how to properly migrate my schema when a field in my model needs to become a different type.
I start with a simple model User
with an array of type String
called friends
@Model
final class User {
@Attribute(.unique) var id: String
var friends: [String]?
}
Now I want to change the type of friends
to [User]?
but I am unsure how to make a migration plan for this. I created two versioned schemas
enum UserSchemaV1: VersionedSchema {
static var versionIdentifier = Schema.Version(1, 0, 0)
static var models: [any PersistentModel.Type] {
[User.self]
}
@Model
final class User {
@Attribute(.unique) var id: String
var friends: [String]?
}
}
enum UserSchemaV2: VersionedSchema {
static var versionIdentifier = Schema.Version(2, 0, 0)
static var models: [any PersistentModel.Type] {
[User.self]
}
@Model
final class User {
@Attribute(.unique) var id: String
var friends: [User]?
}
}
Then I make a migration plan
enum UsersMigrationPlan: SchemaMigrationPlan {
static var stages: [MigrationStage] {
[migrateV1toV2]
}
static var schemas: [any VersionedSchema.Type] {
[UserSchemaV1.self, UserSchemaV2.self]
}
static let migrateV1toV2 = MigrationStage.custom(
fromVersion: UserSchemaV1.self,
toVersion: UserSchemaV2.self,
willMigrate: nil,
didMigrate: nil
)
}
And I make a container using my migration plan
let container: ModelContainer
init() {
do {
container = try ModelContainer(for: User.self,
migrationPlan: UsersMigrationPlan.self
)
} catch {
fatalError("Failed to initialize user model container")
}
}
I also use a typealias so I can keep using User
in my code
typealias User = UserSchemaV2.User
But no matter what I try I get an error when running my code
Thread 1: Fatal error: Unknown related type - User
In the closure for v2 of the Schema
set {
_$observationRegistrar.withMutation(of: self, keyPath: \.friends) {
self.setValue(forKey: \.friends, to: newValue)
}
}
What am I misunderstanding about migrating my schema with this change? Is this something that's possible when doing a schema migration? Is there a simple/better/easier way to modify my schema to change the type of the field?