データモデルを更新します
項目一覧
Atlas Device Sync を使用してアプリケーションを開発していると、次のような場合など、ある時点でスキーマに変更を加える必要がある場合があります。
すでに同期されているオブジェクトに新しいプロパティを追加する
すでに同期されているオブジェクトからプロパティを削除します
プロパティに保存されている型を変更する
オプションのプロパティを必須に更新します
スキーマの変更がアプリにどのように影響するかをより理解しやすくするために、それらを「重大な変更以外」の変更と「重大な変更」として特徴付けます。
Atlas App Services は、同期された Realm に対する重大なスキーマ変更を提供し、古いクライアントが新しいクライアントと同期できるようにします。
ただし、スキーマの重大な変更には一定の計画と作業が必要になるため、可能な限り回避する必要があります。
重大な変更
古いクライアント(新しいコードとスキーマに更新されていないクライアント)は、古いスキーマ定義を介してデータにアクセスする必要があるため、スキーマの変更を重大な変更は困難です。 更新されたクライアントは、新しいスキーマの変更を操作する必要があります。
注意
Atlas App Services UI を使用して重大な変更を行う
スキーマの重大な変更や破壊的な変更には特別な処理が必要になるため、 App Services CLIまたはGithubによる自動配置によるこれらの変更はサポートされていません。 代わりに、App Services UI で重大な変更を行う必要があります。
重大な変更と重大でない変更のクイック リファレンス
重大な変更とは、処理する追加のアクションが必要になるサーバー側のスキーマで行う変更です。 サーバー側のスキーマを変更するには、バックエンドで同期を終了してから、同期を再度有効にする必要があります。 スキーマの変更が大きいと、クライアントが Realm を開くことができなくなったり、サーバー側のドキュメントがクライアント側のアプリケーションに同期できない場合にデータが失われたりします。 アプリケーションがクライアント リセットから自動的に回復することを妨げます。
重大じゃない変更とは、アプリで追加の処理が必要になることなく、サーバー側スキーマまたはオブジェクトモデルで実行できる変更です。 追加の変更とも呼ばれ、同期された Realm に自動的に適用されます。
注意
重大じゃない変更をクライアントに適用するには移行が必要になる場合があります
サーバー側のスキーマに重大じゃない変更のみを行う場合、追加のアクションは必要ありません。 ただし、これらの変更をクライアント オブジェクトモデルに適用しようとする場合は、移行を実行する必要がある場合があります。 クライアント デバイスに既存の Realm ファイルがある場合は、移行を実行する必要があります。 詳細については、ご希望の SDK の「 オブジェクト スキーマの変更 」ページを参照してください。
次の図は、スキーマ変更の種類と、変更を実行するために実行されるプロセスを示していGo 。 これらの変更のそれぞれについて、以下の表とセクションで詳しく説明しています。
この表は、各変更のタイプと、重大な変更であるか重大でない変更かをまとめています。
変化のタイプ | サーバーサイド スキーマ | クライアント側オブジェクトモデル |
---|---|---|
NULLではない | NULLではない | |
NULLではない | NULLではない | |
NULLではない | NULLではない | |
NULLではない | NULLではない | |
重大発生 | NULLではない | |
重大発生 | NULLではない | |
重大発生* | 重大発生* | |
重大発生* | 重大発生* | |
重大発生 | 重大発生 | |
重大発生 | 重大発生 |
Tip
プロパティの名前を変更する
プロパティまたはオブジェクトの名前を変更することは重大な変更ですが、一部の Realm SDK ではプロパティ名を再マッピングする回避策が提供されています。 詳細については、「 プロパティ名の変更 」を参照してください。
開発モードと重大な変更
2023 年 9 月 13 日以降に作成された App Services アプリに適用されます。
年 9 月 日以降に作成された 開発モード の App Services アプリは、クライアント コードから同期されたオブジェクト スキーマに重大な変更を加える2023性があり13 。
開発モードで重大な変更を加えるための詳細については、 「 開発モード 」を参照してください。
開発モードは本番環境での使用には適していません。 開発モードを使用する場合は、アプリを本番環境に移行する前に必ずこのモードを無効にしてください。
オブジェクトタイプの追加
追加の処理なしで、サーバー側スキーマまたはクライアント オブジェクトモデルのいずれかにオブジェクトタイプを追加できます。
サーバー側のスキーマとクライアント オブジェクトモデルの両方にオブジェクト型を追加する場合は、オブジェクトモデルにオブジェクト型を追加し、開発モードを使用してApp Servicesがサーバー側のスキーマ更新を処理できるようにできます。 または、オブジェクトタイプをモデルとスキーマの両方に手動で追加することもできます。
注意
これらの変更により再同期がtriggerされる可能性があります
新しいオブジェクトタイプを追加すると、コレクションのドキュメントが取得され、App Services に再挿入され、新しい値が取得されます。 これは期待される動作ですが、このプロセスの実行中に変更の伝達が一時的に停止します。
プロパティにデフォルト値を追加する
オブジェクトの必須プロパティにデフォルト値を追加できます。 この必須プロパティが欠落している Atlas ドキュメントを コレクションに挿入すると、Realm クライアントはプロパティをデフォルト値に設定します。 ただし、クライアントがプロパティを変更するか、Atlas でドキュメントを直接更新するまで、Atlas ドキュメントの同じプロパティは空のままになります。
既存の Atlas ドキュメントを変更する際にデフォルト値がどのように役立つかについて詳しくは、「必須プロパティを追加する 」を参照してください。
警告
デフォルト値の型とプロパティの型が同じであることを確認します
デフォルトの フィールドには型検証はありません。 デフォルトのフィールドの型とプロパティの型が同じでない場合、エラーはドキュメントに必須フィールドが欠落していることを示します。
必須 プロパティを追加する
クライアントのオブジェクトモデルに必須プロパティを追加し、開発モードを使用して App Services がサーバー側のスキーマ更新を推測できるようにします。 または、必要なプロパティをクライアント モデルと Atlas スキーマの両方に手動で追加することもできます。 ただし、既存の Atlas ドキュメントを変更する必要がないようにするには、 プロパティを任意にすることを検討してください。
注意
スキーマ サブセットにない必須プロパティはデフォルトでゼロになります
クライアントは、必須プロパティを含まないスキーマ サブセットを使用して Realm を開くことができます。 サーバーは、ドキュメントが同期されるときに、欠落している必須値フィールドにゼロまたは空白の値(プロパティの種類に応じて 0、""、0.0 など)を入力します。
既存の Atlas ドキュメントの変更
新しい必須プロパティを追加する場合は、既存のドキュメントを新しいプロパティで更新する必要があります。そうしないと、クライアントに同期しません。 これにより、クライアントユーザーにはデータが失われたという認識を与える可能性があります。 影響を受けるドキュメントの各ドキュメントに新しいプロパティを追加し、そのドキュメントに 値を入力することで、この問題を解決します。 クライアント スキーマと一致するようにドキュメントを更新すると、それらはクライアント アプリケーションに同期されます。
新しい必須プロパティを追加すると、App Services は更新されたスキーマごとに新しい値を持つドキュメントをコレクションから検索します。 App Services はそれらのドキュメントを反復処理し、新しい 値を取得するために再挿入します。 これは期待される動作ですが、このプロセスの実行中に変更の伝達が一時的に停止します。
重要
App Services は、同期されていないドキュメントを追跡するために __realm_sync.unsynced_documents
コレクションを使用します。 必須 プロパティを追加すると、再同期プロセスによってこのコレクションが100 、 000ドキュメントの制限を超えることができます。 この場合、次の 2 つのオプションがあります。
行っている変更が重大じゃない変更であっても、同期を終了 して再度有効化します。
サポートに連絡し、同期できないドキュメント数の一時的な増加をリクエストします。
オプション プロパティを追加する
サーバー側のスキーマとクライアント オブジェクトモデルの両方にオプションのプロパティを追加する場合は、オブジェクトモデルにオプションのプロパティを追加し、開発モードを使用して App Services がサーバー側のスキーマ更新を推測できるようにします。 または、オプションのプロパティをモデルとスキーマの両方に手動で追加できます。
注意
これらの変更により再同期がtriggerされる可能性があります
新しい任意プロパティを追加すると、更新されたスキーマごとに新しい値を持つドキュメントがコレクション向けに検索されます。 これらのドキュメントを反復処理し、App Services に再挿入して新しい 値を取得します。 これは期待される動作ですが、このプロセスの実行中に変更の伝達が一時的に停止します。
オブジェクトタイプの削除
クライアントのオブジェクトモデルからオブジェクトを重大じゃない変更として削除できます。 サーバー側スキーマからオブジェクトを削除すると、重大な変更になります。 このため、クライアント側のオブジェクトモデルからのみオブジェクトタイプを削除し、サーバー側のスキーマに保持することをお勧めします。
プロパティを削除する
クライアント側のオブジェクトモデルから任意または必須のプロパティを削除し、サーバー側のスキーマに配置することができます。 これは、オブジェクトモデルに対する重大じゃない変更です。
サーバー側スキーマからプロパティを削除する場合、重大な変更になります。 このため、クライアント側のオブジェクトモデルからのみプロパティを削除し、サーバー側のスキーマに配置することをお勧めします。
下位互換性を維持するために、クライアント側のオブジェクトモデルからプロパティを削除しても、データベースからプロパティは削除されません。 代わりに、新しいオブジェクトは削除されたプロパティを保持し、App Services は値を適切な空の値に設定します。たとえば、null 可能なプロパティの場合はnull
、整数値の場合は 0、string 値の場合は空の string などです。
オブジェクト名の変更
サーバー側スキーマとクライアント側オブジェクトモデルの両方でオブジェクト名を変更することは、重大な変更です。 ただし、一部の SDK では、新しいオブジェクト名をスキーマ内の既存の名前にマッピングするための API が提供されています。 これにより、クライアント上のオブジェクトの名前を変更できますが、サーバー上のオブジェクト名は変更できません。 この方法では、移行がトリガーされないようにします。 オブジェクト名マッピングは次の SDK でサポートされています。
Kotlin
Java
.NET
Flutter
名前マッピングがオプションでない場合は、パートナーコレクション戦略の実装を検討してください。この場合は、既存のコレクションとスキーマを保持し、新しいスキーマで新しいコレクションを作成します。
パートナー コレクション戦略を使用する代わりにオブジェクトの名前を変更する場合は、同期を終了し、スキーマを手動で更新してから、同期を再度有効にする必要があります。 さらに、同期を復元するには、クライアント アプリケーションがクライアント リセットを実行する必要があります。 デフォルトのクライアント リセット モードでは、クライアントはリセットする前に同期されていない変更の回復を試みます。
注意
開発モードでは、重大な変更に対してスキーマが自動的に更新されることはありません。
プロパティ名の変更
サーバー側スキーマとクライアント側のオブジェクトモデルの両方でプロパティ名を変更することは、重大な変更です。 ただし、一部の SDK では、新しいプロパティ名をスキーマ内の既存の名前にマッピングするための API が提供されています。 これにより、クライアント上のプロパティの名前を変更できますが、サーバー上のプロパティ名は変更できません。 この方法では、移行がトリガーされないようにします。 プロパティ名マッピングは次の SDK でサポートされています。
警告
既存のドキュメントの更新
サーバー側スキーマでプロパティ名を変更する場合は、その新しいプロパティ名で既存のドキュメントを更新する必要があります。そうしないと、ドキュメントはクライアントに同期されません。 これにより、クライアントユーザーにはデータが失われたという認識を与える可能性があります。
名前マッピングがオプションでない場合は、パートナーコレクション戦略の実装を検討してください。この場合は、既存のコレクションとスキーマを保持し、新しいスキーマで新しいコレクションを作成します。
パートナー コレクション戦略を使用する代わりにプロパティの名前を変更する場合は、同期を終了し、スキーマを手動で更新してから、同期を再度有効にする必要があります。 さらに、同期を復元するには、クライアント アプリケーションがクライアント リセットを実行する必要があります。 デフォルトのクライアント リセット モードでは、クライアントはリセットする前に同期されていない変更の回復を試みます。
同期を終了して再度有効にする場合は、既存の Atlas ドキュメントも更新して、クライアント アプリケーションと同期できるようにする必要があります。 この追加処理を行わないと、それらのドキュメントは同期されず、クライアントではデータが失われたと表示される可能性があります。 この問題は、次の 2 つの方法で解決できます。
各ドキュメントの古いフィールド名を新しいスキーマに一致するように変更します
新しいスキーマと一致する名前を持つ各ドキュメントに新しいフィールドを追加し、古いフィールドからそのドキュメントに値をコピーします
これらの変更を行うと、適切なドキュメントがクライアント アプリケーションに同期されます。
プロパティタイプを変更して、名前を維持
プロパティのタイプを変更すると、サーバー側スキーマとクライアント側のオブジェクトモデルの両方に重大な変更が生じます。
警告
既存のドキュメントの更新
サーバー側スキーマでプロパティのタイプを変更する場合は、その新しいプロパティタイプで既存のドキュメントを更新する必要があります。そうしないと、ドキュメントはクライアントに同期されません。 これにより、クライアントユーザーにはデータが失われたという認識を与える可能性があります。
プロパティのタイプを変更する代わりに、パートナー コレクション戦略の実装を検討してください。この場合は、既存のコレクションとスキーマを保持し、新しいスキーマで新しいコレクションを作成します。
パートナー コレクション戦略を使用する代わりにプロパティのタイプを変更する場合は、同期を終了し、スキーマを手動で更新してから、同期を再度有効にする必要があります。 さらに、同期を復元するには、クライアント アプリケーションがクライアント リセットを実行する必要があります。 デフォルトのクライアント リセット モードでは、クライアントはリセットする前に同期されていない変更の回復を試みます。
注意
開発モードでは、重大な変更に対してスキーマが自動的に更新されることはありません。
同期を終了して再度有効にする場合は、既存の Atlas ドキュメントも更新して、クライアント アプリケーションと同期できるようにする必要があります。 この追加処理を行わないと、それらのドキュメントは同期されず、クライアントではデータが失われたと表示される可能性があります。 この問題は、次の 2 つの方法で解決できます。
各ドキュメントの古いフィールド型を新しいスキーマに一致するように変更します
新しいスキーマに一致するタイプを持つ各ドキュメントに新しいフィールドを追加し、古いフィールドからそのフィールドに値をコピーして、タイプを変換します
これらの変更を行った後、適切なドキュメントがクライアント アプリケーションに再度同期されます。
プロパティのステータスを任意から必須の間で変更する
プロパティのステータスを任意から必須の間で変更すると、サーバー側スキーマとクライアント側のオブジェクトモデルの両方に重大な変更が生じます。
警告
既存のドキュメントの更新
サーバー側スキーマでプロパティのステータスを変更する場合は、その新しいプロパティ型で既存のドキュメントを更新する必要があります。そうしないと、ドキュメントはクライアントに同期されません。 これにより、クライアントユーザーにはデータが失われたという認識を与える可能性があります。
プロパティのステータスを変更する代わりに、パートナー コレクション戦略の実装を検討してください。この場合は、既存のコレクションとスキーマを保持し、新しいスキーマで新しいコレクションを作成します。
パートナー コレクション戦略を使用する代わりにプロパティのステータスを変更する場合は、同期を終了し、スキーマを手動で更新してから、同期を再度有効にする必要があります。 さらに、同期を復元するには、クライアント アプリケーションがクライアント リセットを実行する必要があります。 デフォルトのクライアント リセット モードでは、クライアントはリセットする前に同期されていない変更の回復を試みます。
注意
開発モードでは、重大な変更に対してスキーマが自動的に更新されることはありません。
パートナー コレクション戦略の使用
パートナー コレクションは、元のコレクションと同じデータを含みますが、新しいスキーマ定義が設定されているコレクションです。 パートナー コレクションは データベーストリガー を使用して、データが両方向に書き込まれるようにします。つまり、1つのコレクションが書き込まれると、他のコレクションも に書き込まれます(新しいスキーマにはデータ変更が必要)。
パートナー コレクション戦略を使用してスキーマの重大な変更を実装するには、「スキーマの重大な変更の作成 」を参照してください。