ドキュメントを引用して、
リレーショナルデータベースとは異なり、AppEngineデータストアでは特定の種類のすべてのエンティティが同じプロパティを持っている必要はありません。アプリケーションは、SDKに含まれているライブラリ、または独自のコードを使用して、データモデルを指定および適用できます。
これは「ソフトスキーマ」とも呼ばれます。データストアは実際にはスキーマを実行しませんが、アプリケーションレベルのコード(独自のコードまたはライブラリ内)を介して、ソフトな種類のスキーマを多かれ少なかれシミュレートできます。
したがって、(ライブラリを介して、または独自のコードで)「この属性が存在する必要がある」という制約を適用し、特定のエンティティが実際にはその属性を持たない場合(別の「ソフトスキーマ」に基づいて挿入されたため)たとえば、アプリの別のバージョン)の場合、制約がチェックされる時点で、アプリケーションレベルのコードまたはライブラリがこのソフト制約の違反を示すために使用することを選択した例外が発生します。
そのような制約を表現しない場合、欠落している属性には、コードまたはライブラリによって提供されるデフォルト値が含まれるか、「デフォルトのデフォルト」が適用されます。これは通常null
、JavaまたはNone
Pythonにあると思います。
アプリのバージョンが異なれば、使用するランタイムも異なり(Javaの場合もあれば、Pythonの場合もあります)、ランタイムも同じデータストアを使用するため、ここではJavaとPythonの区別は重要ではありません。
あなたの特定の例(デフォルトは提供されておらず、必須のプレゼンスについてのアサーションは作成されていません)では、どちらかのバージョンからユーザーを追加すると、他のバージョンからも表示され、属性が欠落しているように見えますnull
(ただし、私がしている制約がある可能性があります)気づいていません。その場合、ライブラリがこれらの制約を検証しようとして、違反していることを確認すると、例外が発生するはずです)。
null
一般的に、「オプションの」属性(正当に欠落している可能性のある属性/ / None
、またはそのような場合に明示的なデフォルトがあり、古いバージョンで記述されたエンティティが引き続き正しく読み取れる可能性がある属性)を追加することについて心配する必要はありませんが、他の種類の属性変更の場合(以前に欠落していた属性またはオプションの属性を必須にする、他の制約を追加するなど)、移行が実行不可能です。
特に、以前のアプリバージョンにロールバックする機能が必要な場合、移行は実行できない可能性があります(実際、これらの場合、他の操作が問題になります。たとえば、古いバージョンでは制約を追加するのと同じくらい問題が発生します。新しいバージョンで削除された制約に違反する、新しいデータに入力されたデータを処理できません)。
したがって、実際には必ずしも単純な問題ではありませんが、それでもこのように考えると役立ちます。データストア自体にはスキーマがなく、使用することを選択したアプリやライブラリのみが、アプリレベルで必要な制約を適用します。基盤となるエンティティは、それ自体、実際には任意の属性のセットを持っています。つまり、「ソフトスキーマ」、アプリケーションレベルのスキーマ、基盤となるデータレイヤーに「実際の」スキーマはありません。