Alterar um modelo de objeto - React Native 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.
Ao atualizar seu esquema de objetos, você deve incrementar a versão do esquema e realizar uma migração.
Se a atualização do esquema adicionar propriedades opcionais ou remover propriedades, o Realm poderá executar a migração automaticamente. Basta incrementar o schemaVersion
.
Para atualizações de esquema mais complexas, você também deve especificar manualmente a lógica de migração em uma função do migration
. Isso pode incluir alterações como:
Adicionando propriedades necessárias que devem ser preenchidas com valores padrão
Combinando campos
Renomeando um campo
Como alterar o tipo de campo
Convertendo de um objeto para um objeto incorporado
Dica
Ignorar migração durante o desenvolvimento
Ao desenvolver ou depurar seu aplicativo, você pode preferir excluir o domínio em vez de migrá-lo. Use o BaseConfiguration.deleteRealmIfMigrationNeeded propriedade para excluir o banco de dados automaticamente quando uma incompatibilidade de esquema exige uma migração.
Nunca libere um aplicativo para produção com esta propriedade 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 números inteiros crescentes que você pode incluir na configuração do domínio. Se um aplicativo cliente não especificar um número de versão, o padrão do domínio será a versão 0
.
Importante
Incrementar versões monotonicamente
As migrações devem atualizar um território para uma versão de esquema superior. O Realm exibe um erro se um aplicativo cliente usar uma versão do esquema inferior à versão atual do domínio ou se a versão do esquema especificada for igual à versão atual do domínio, mas incluir um esquema diferente.
Migrações
Uma migração é uma função que atualiza um domínio e quaisquer objetos que ele contém de uma versão de esquema para uma versão mais nova. Migrações permitem a você alterar seus esquemas de objetos ao longo do tempo para acomodar novos recursos e refatores.
Quando você cria uma Configuração com uma versão de esquema maior que a versão atual do domínio, o Realm executa uma função de migração que você define. 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.
O Realm migra automaticamente certas alterações, como propriedades novas e excluídas, mas não define automaticamente valores para novas propriedades, a menos que o esquema de objeto atualizado especifique um valor padrão. Você pode definir lógica adicional na função de migração para personalizar ainda mais os valores da propriedade.
Adicionar uma propriedade
Para adicionar uma propriedade a um esquema, adicione a nova propriedade à classe do objeto e defina um schemaVersion
do objeto Configuration
.
Exemplo
Um domínio utilizando versão de esquema 0
, o padrão, tem um tipo de objeto Person
com uma propriedade firstName
e lastName
. Você decide adicionar uma propriedade age
à classe Person
.
Para migrar o domínio para estar em conformidade com o esquema de Person
atualizado, defina a versão do esquema do domínio no Configuration
como 1
. Finalmente, passe o objeto de configuração para o método createRealmContext()
.
class Person extends Realm.Object { static schema = { name: 'Person', properties: { _id: 'string', firstName: 'string', lastName: 'string', // add a new property, 'age' to the schema age: 'int', }, }; } const config = { schema: [Person], // Increment the 'schemaVersion', since 'age' has been added to the schema. // The initial schemaVersion is 0. schemaVersion: 2, }; // pass the configuration object with the updated 'schemaVersion' to // createRealmContext() const {RealmProvider} = createRealmContext(config);
class Person extends Realm.Object<Person> { _id!: string; firstName!: string; lastName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { _id: 'string', firstName: 'string', lastName: 'string', // add a new property, 'age' to the schema age: 'int', }, }; } const config: Realm.Configuration = { schema: [Person], // Increment the 'schemaVersion', since 'age' has been added to the schema. // The initial schemaVersion is 0. schemaVersion: 2, }; // pass the configuration object with the updated 'schemaVersion' to // createRealmContext() const {RealmProvider} = createRealmContext(config);
Excluir uma propriedade
Para excluir uma propriedade de um esquema, remova a propriedade da classe do objeto e configure um schemaVersion
do objeto Configuração. Excluir uma propriedade não afetará os objetos existentes.
Exemplo
Um Realm usando a versão de esquema 0
, o padrão, tem um tipo de objeto Person
com uma propriedade lastName
. Você quem decide remover a propriedade do esquema.
Para migrar o domínio para estar em conformidade com o esquema de Person
atualizado, defina a versão do esquema do domínio como 1
no objeto Configuration
. Finalmente, passe o objeto de configuração para o método createRealmContext()
.
class Person extends Realm.Object { static schema = { name: 'Person', properties: { _id: 'string', firstName: 'string', age: 'int', }, }; } const config = { schema: [Person], // Increment the 'schemaVersion', since 'lastName' has been removed from the schema. // The initial schemaVersion is 0. schemaVersion: 1, }; // pass the configuration object with the updated 'schemaVersion' to createRealmContext() const {RealmProvider} = createRealmContext(config);
class Person extends Realm.Object<Person> { _id!: string; firstName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { _id: 'string', firstName: 'string', age: 'int', }, }; } const config: Realm.Configuration = { schema: [Person], // Increment the 'schemaVersion', since 'lastName' has been removed from the schema. // The initial schemaVersion is 0. schemaVersion: 1, }; // pass the configuration object with the updated 'schemaVersion' to createRealmContext() const {RealmProvider} = createRealmContext(config);
Renomear uma propriedade
Para renomear uma propriedade de objeto, altere o nome da propriedade no esquema de objeto e, em seguida, crie uma configuração de área com uma versão de esquema incrementada e uma função de migração que atualiza objetos existentes para usar o novo nome de propriedade.
As migrações não permitem renomear diretamente uma propriedade. Em vez disso, você pode criar uma nova propriedade com o nome atualizado, copiar o valor da propriedade antiga e, em seguida, excluir a propriedade antiga.
Exemplo
Um realm usando a versão do esquema 0
, o padrão, tem um tipo de objeto Person
. O esquema original tinha um campo firstName
e lastName
. Mais tarde, você decide que a classe Person
deve usar um campo fullName
combinado e remover os campos firstName
e lastName
separados.
Para migrar o realm para estar em conformidade com o esquema Person
atualizado, crie um objeto de Configuração e defina a versão do esquema do realm como 1
e defina uma função de migração que estabelece o valor de fullName
com base no firstName
e lastName
propriedades. Finalmente, passe o objeto de configuração para o método createRealmContext()
.
class Person extends Realm.Object { static schema = { name: 'Person', properties: { _id: 'string', // rename the 'firstName' and 'lastName' property, to 'fullName' // in the schema fullName: 'string', age: 'int', }, }; } const config = { schema: [Person], // Increment the 'schemaVersion', since 'fullName' has replaced // 'firstName' and 'lastName' in the schema. // The initial schemaVersion is 0. schemaVersion: 1, onMigration: (oldRealm, newRealm) => { // only apply this change if upgrading schemaVersion if (oldRealm.schemaVersion < 1) { const oldObjects = oldRealm.objects(Person); const newObjects = newRealm.objects(Person); // loop through all objects and set the fullName property in the // new schema for (const objectIndex in oldObjects) { const oldObject = oldObjects[objectIndex]; const newObject = newObjects[objectIndex]; newObject.fullName = `${oldObject.firstName} ${oldObject.lastName}`; } } }, }; // pass the configuration object with the updated 'schemaVersion' and // 'migration' function to createRealmContext() const {RealmProvider} = createRealmContext(config);
class Person extends Realm.Object<Person> { _id!: string; fullName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { _id: 'string', // rename the 'firstName' and 'lastName' property, to 'fullName' // in the schema fullName: 'string', age: 'int', }, }; } class OldObjectModel extends Realm.Object<OldObjectModel> { _id!: string; firstName!: string; lastName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { _id: 'string', firstName: 'string', lastName: 'string', }, }; } const config: Realm.Configuration = { schema: [Person], // Increment the 'schemaVersion', since 'fullName' has replaced // 'firstName' and 'lastName' in the schema. // The initial schemaVersion is 0. schemaVersion: 1, onMigration: (oldRealm: Realm, newRealm: Realm) => { // only apply this change if upgrading schemaVersion if (oldRealm.schemaVersion < 1) { const oldObjects: Realm.Results<OldObjectModel> = oldRealm.objects(OldObjectModel); const newObjects: Realm.Results<Person> = newRealm.objects(Person); // loop through all objects and set the fullName property in the // new schema for (const objectIndex in oldObjects) { const oldObject = oldObjects[objectIndex]; const newObject = newObjects[objectIndex]; newObject.fullName = `${oldObject.firstName} ${oldObject.lastName}`; } } }, }; // pass the configuration object with the updated 'schemaVersion' and // 'migration' function to createRealmContext() const {RealmProvider} = createRealmContext(config);
Importante
Domínios sincronizados
Os domínios sincronizados oferecem suporte apenas a alterações não separáveis - também chamadas de aditivas - para garantir que os clientes mais antigos possam sincronizar com os clientes mais recentes. Como as renomeações completas exigem que você exclua a propriedade antiga, não é possível renomear uma propriedade sincronizada sem exigir um reinício do cliente. Em vez disso, considere adicionar a propriedade renomeada sem excluir a propriedade antiga. Alternativamente, utilize mapTo para armazenar dados utilizando o nome interno existente, mas permita que seu código utilize um nome diferente.
Modificar um tipo de propriedade
Para modificar o tipo de propriedade, defina o tipo de propriedade do campo que deseja modificar para o novo tipo de dados. Em seguida, defina uma chamada de resposta schemaVersion
e uma migration
do objeto Configuração .
Observação
Os domínios sincronizados somente suportam alterações não interruptivas para garantir que os clientes mais antigos possam sincronizar com os mais novos. Isso significa que os domínios sincronizados não suportam a modificação do tipo de propriedade de um esquema.
Exemplo
Um realm usando a versão do esquema 0
, o padrão, tem um tipo de objeto Person
. O esquema original tinha um _id
com um tipo de propriedade de int
. Mais tarde, você decide que o campo Person
da turma _id
deve ser do tipo ObjectId
e atualiza o esquema.
Para migrar o domínio para estar em conformidade com o esquema Person
atualizado, crie um objeto Configuration
e defina a versão do esquema do domínio como 1
e defina uma função de migração para converter o tipo inteiro em um tipo Object ID
. Finalmente, passe o objeto de configuração para o método createRealmContext()
.
class Person extends Realm.Object { static schema = { name: 'Person', properties: { // update the data type of '_id' to be 'objectId' within the schema _id: 'objectId', firstName: 'string', lastName: 'string', }, }; } const config = { schema: [Person], // Increment the 'schemaVersion', since the property type of '_id' // has been modified. // The initial schemaVersion is 0. schemaVersion: 1, onMigration: (oldRealm, newRealm) => { if (oldRealm.schemaVersion < 1) { const oldObjects = oldRealm.objects(Person); const newObjects = newRealm.objects(Person); // loop through all objects and set the _id property // in the new schema for (const objectIndex in oldObjects) { const oldObject = oldObjects[objectIndex]; const newObject = newObjects[objectIndex]; newObject._id = new Realm.BSON.ObjectId(oldObject._id); } } }, }; // Pass the configuration object with the updated // 'schemaVersion' and 'migration' function to createRealmContext() const {RealmProvider} = createRealmContext(config);
class Person extends Realm.Object<Person> { _id!: Realm.BSON.ObjectId; firstName!: string; lastName!: string; age!: number; static schema: ObjectSchema = { name: 'Person', properties: { // Update the data type of '_id' to be 'objectId' within the schema. _id: 'objectId', firstName: 'string', lastName: 'string', }, }; } // `OldObjectModel` is only used for type injection for `oldRealm`. It is // not related to the `Person` object model. interface OldObjectModel { _id: Realm.BSON.ObjectId; firstName: string; lastName: string; age: number; } const config: Realm.Configuration = { schema: [Person], // Increment the 'schemaVersion', since the property type of '_id' // has been modified. // The initial schemaVersion is 0. schemaVersion: 1, onMigration: (oldRealm: Realm, newRealm: Realm) => { if (oldRealm.schemaVersion < 1) { const oldObjects: Realm.Results<OldObjectModel> = oldRealm.objects(Person); const newObjects: Realm.Results<Person> = newRealm.objects(Person); // Loop through all objects and set the _id property // in the new schema. for (const objectIndex in oldObjects) { const oldObject = oldObjects[objectIndex]; const newObject = newObjects[objectIndex]; newObject._id = new Realm.BSON.ObjectId(oldObject._id); } } }, }; // Pass the configuration object with the updated // 'schemaVersion' and 'migration' function to createRealmContext(). const {RealmProvider} = createRealmContext(config);