Alterar um modelo de objetos - Kotlin SDK
Nesta página
Observação
Modificar Propriedades do Esquema de um Domínio Sincronizado
A página seguinte demonstra como modificar as propriedades do esquema de um Realm local. Saiba como modificar as propriedades do esquema de um Realm sincronizado.
Visão geral
Você pode fazer alterações no seu esquema de objetos depois de criar o seu Objeto de Realm. Dependendo do tipo de alterações feitas no esquema, elas podem ser aplicadas automaticamente ou exigir uma atualização manual para o novo esquema.
O Realm atualizará automaticamente um esquema de objeto do Realm quando você adicionar ou excluir uma propriedade de um modelo de objeto do Realm. Você só precisa atualizar a versão do esquema.
Para todas as outras alterações de esquema, você deve migrar manualmente instâncias antigas de um determinado objeto para o novo esquema.
Dica
Ignorar migração durante o desenvolvimento
Ao desenvolver ou depurar seu aplicação, talvez você prefira excluir o Realm em vez de migrá-lo. Use o sinalizador deleteRealmifMigrationNeeded para excluir o banco de dados de dados automaticamente quando uma incompatibilidade de esquema exigir uma migração.
Nunca libere um aplicativo para produção com esta sinalização definida como true
.
Versão do esquema
Uma versão do esquema de esquema de domínio identifica o estado de um esquema de território em algum momento no tempo. Realm controla a versão do esquema de cada realm e usa-o para mapear os objetos em cada realm para o esquema correto.
As versões de esquemas são inteiros crescentes que você pode opcionalmente incluir na configuração do Realm quando abrir um Realm. Se uma aplicação cliente não especificar um número de versão quando abrir um Realm, o Realm assumirá como padrão a versão 0
.
Importante
Incrementar versões monotonicamente
As migrações devem atualizar um Realm para uma versão superior do esquema. O Realm vai gerar um erro se um aplicativo cliente abrir um realm com uma versão do esquema inferior à versão atual do realm ou se a versão do esquema especificada for igual à versão atual do realm, mas incluir esquemas de objetos diferentes.
Migração
As atualizações do esquema são chamadas de migrações no Realm. Uma migração atualiza um Realm e qualquer objeto que ele contém de uma versão do esquema para uma versão mais recente.
Sempre que você abre um Realm existente com uma versão do esquema maior que a versão atual do Realm, pode fornecer uma função de migração que define qualquer lógica adicional necessária para a atualização do esquema. Por exemplo:
Definindo valores de propriedade
Combinando ou dividindo campos
Renomeando um campo
Como alterar o tipo de campo
A função tem acesso ao número da versão do domínio e atualiza os objetos do domínio de forma incremental para que fiquem em conformidade com o novo esquema.
Uma migração local é uma migração para um realm que não é sincronizado automaticamente com outro realm.
Observação
Para modificar as propriedades do esquema de um domínio sincronizado, consulte Atualizar um Modelo de Dados na documentação do Atlas Device Sync.
Atualize esquemas automaticamente
Se a atualização do esquema adicionar ou remover propriedades, o Realm poderá executar a migração automaticamente. Basta incrementar o schemaVersion
.
Adicionar uma propriedade
Para adicionar uma propriedade a um esquema:
Adicione a nova propriedade à definição
RealmObject
.Configure a versão do esquema através do construtor RealmConfiguration .
O Realm define automaticamente valores para novas propriedades se o esquema de objetos atualizado especificar um valor padrão. Se o esquema de objetos atualizado não especificar um valor padrão, você deverá definir manualmente os valores para a nova propriedade por meio de uma função de migração.
Exemplo
Um Realm que usa a versão do esquema 1
tem um Tipo de objeto de Realm Person
com propriedade de nome, sobrenome e idade:
// Realm schema version 1 class Person : RealmObject { var firstName: String = "" var lastName: String = "" var age: Int = 0 }
O desenvolvedor adiciona um campo email
à classe Person
:
// Realm schema version 2 class Person : RealmObject { var firstName: String = "" var lastName: String = "" var age: Int = 0 var email: String? = null }
Para alterar o Realm para estar em conformidade com o esquema Person
atualizado, o desenvolvedor define a versão do esquema do Realm como 2
:
val config = RealmConfiguration.Builder( schema = setOf(Person::class) ) .schemaVersion(2) // Sets the new schema version to 2 .build() val realm = Realm.open(config)
Excluir uma propriedade
Para excluir uma propriedade de um esquema:
Remova a propriedade da classe do objeto.
Configure a versão do esquema através do construtor RealmConfiguration .
Excluir uma propriedade não afetará os objetos existentes.
Exemplo
Um Realm que usa a versão do esquema 2
tem um Tipo de objeto de Realm Person
com propriedade de nome, sobrenome, idade e e-mail:
// Realm schema version 2 class Person : RealmObject { var firstName: String = "" var lastName: String = "" var age: Int = 0 var email: String? = null }
O desenvolvedor remove o campo age
da classe Person
:
// Realm schema version 3 class Person : RealmObject { var firstName: String = "" var lastName: String = "" // var age: Int = 0 var email: String? = null }
Para alterar o Realm para estar em conformidade com o esquema Person
atualizado, o desenvolvedor define a versão do esquema do Realm como 3
:
val config = RealmConfiguration.Builder( schema = setOf(Person::class) ) .schemaVersion(3) // Sets the new schema version to 3 .build() val realm = Realm.open(config)
Migre esquemas manualmente
Para atualizações de esquema mais complexas, o Realm exige que você migre manualmente instâncias antigas de um determinado objeto para o novo esquema.
Ao abrir o domínio com o esquema atualizado, você deve fazer o seguinte no RealmConfiguration:
Aumentar a propriedade
schemaVersion
.Defina a lógica de migração usando o migrationContext.
Modificar uma propriedade
Para modificar uma propriedade de objeto (por exemplo, renomear, mesclar, divisão ou alterar o tipo de propriedade):
Altere a propriedade ou propriedades no esquema de objeto.
Abra o Realm com uma versão de esquema incrementada e uma função de migração que mapeia os objeto existentes para usar as nova propriedade.
No exemplo a seguir, o esquema é atualizado para alterar um tipo de propriedade, mesclar duas propriedades em uma nova propriedade e renomear uma propriedade existente:
// Realm schema version 1 (oldObject) class Person : RealmObject { var _id: ObjectId = ObjectId() var firstName: String = "" var lastName: String = "" var age: Int = 0 } // Realm schema version 2 (newObject) class Person : RealmObject { var _id: String = "" // change property type var fullName: String = "" // merge firstName and lastName properties var yearsSinceBirth: Int = 0 // rename property }
Em seguida, a função de migração define a lógica de migração para mapear dados entre as propriedades modificadas no esquema de objeto antigo e o novo esquema de objeto:
// Use the configuration builder to open the realm with the newer schema version // and define the migration logic between your old and new realm objects val config = RealmConfiguration.Builder( schema = setOf(Person::class) ) .schemaVersion(2) // Set the new schema version to 2 .migration(AutomaticSchemaMigration { it.enumerate(className = "Person") { oldObject: DynamicRealmObject, newObject: DynamicMutableRealmObject? -> newObject?.run { // Change property type set( "_id", oldObject.getValue<ObjectId>(fieldName = "_id").toString() ) // Merge properties set( "fullName", "${oldObject.getValue<String>(fieldName = "firstName")} ${oldObject.getValue<String>(fieldName = "lastName")}" ) // Rename property set( "yearsSinceBirth", oldObject.getValue<String>(fieldName = "age") ) } } }) .build() val realm = Realm.open(config)
Observação
Se a atualização do esquema incluir a conversão de um RealmObject para um EmbeddedRealmObject, a função de migração deverá garantir que o objeto incorporado tenha exatamente um objeto pai vinculado a ele. Objetos embarcados não podem existir independentemente de um objeto pai .
Outras tarefas de migração
Para executar outras migrações do esquema de Realm, use as seguintes propriedade da interface AutomaticSchemaMigration.MigrationContext
:
oldRealm: o domínio tal como existia antes da migração com a versão do esquema anterior. A API dinâmica permite localizar objetos de Realm por meio de uma representação de string de seu nome de classe.
newRealm: o Realm tal como existe após a migração usando a nova versão do esquema.
Quaisquer objetos obtidos de oldRealm
e newRealm
são válidos somente no escopo da função de migração.
Ao final da migração, você deve migrar todos os dados afetados pela atualização do esquema do Realm antigo para o novo Realm. Qualquer dado afetado pela atualização do esquema que não for migrado será perdido.
val config = RealmConfiguration.Builder( schema = setOf(Person::class) ) .schemaVersion(2) .migration(AutomaticSchemaMigration { migrationContext -> val oldRealm = migrationContext.oldRealm // old realm using the previous schema val newRealm = migrationContext.newRealm // new realm using the new schema // Dynamic query for all Persons in old realm val oldPersons = oldRealm.query(className = "Person").find() for (oldPerson in oldPersons) { // Get properties from old realm val firstName: String = oldPerson.getValue( propertyName = "firstName", String::class ) // Get objects from old realm as dynamic realm objects val pet: DynamicRealmObject? = oldPerson.getObject( propertyName = "pets" ) } // Get migrated objects from the new realm as mutable objects val oldPerson: DynamicMutableRealmObject? = newRealm.findLatest(oldPersons[0]) oldPerson?.let { it.set("fullName", "Crow T. Robot") } // Create an object in the new realm and set property values val newPerson = newRealm.copyToRealm( DynamicMutableRealmObject.create( type = "Person", mapOf( "_id" to "123456", "fullName" to "Tom Servo", "yearsSinceBirth" to 33, ) ) ) }) .build() val realm = Realm.open(config)