エンティティ キーの作成と使用

各エンティティは、アプリケーションの Datastore インスタンス内で一意のキーによって識別され、次の要素で構成されます。

  • 種類。種類は通常、エンティティが属するモデルクラスの名前ですが、クラスメソッド _get_kind() をオーバーライドすることにより、これを他の文字列に変更できます。
  • 識別子。固有のキー名を識別子として指定します。あるいは、Datastore が整数値の ID を自動的に生成します。

固有のキー名を指定する

次の例では、名前付きパラメータ id を使用して、文字列識別子を持つキーを暗黙的に作成します。

account = Account(
    username='Sandy', userid=1234, email='sandy@example.com',
    id='sandy@example.com')

return account.key.id()  # returns 'sandy@example.com'

キー名を直接設定することもできます。

account.key = ndb.Key('Account', 'sandy@example.com')

# You can also use the model class object itself, rather than its name,
# to specify the entity's kind:
account.key = ndb.Key(Account, 'sandy@example.com')

キーに使用する ID を Datastore で自動的に生成する

次のコードは、自動生成された ID をキーとして使用する方法を示しています。

# note: no id kwarg
account = Account(username='Sandy', userid=1234, email='sandy@example.com')
account.put()
# account.key will now have a key of the form: ndb.Key(Account, 71321839)
# where the value 71321839 was generated by Datastore for us.

キーに祖先パスを使用する

ルート エンティティから始まり、親から子を経由して対象のエンティティに至るまでのエンティティの連なりのことを、エンティティの祖先パスといいます。 エンティティの親、親の親、さらにその親など再帰的に上位のエンティティはすべて、そのエンティティの祖先です。Datastore のエンティティは、ファイルシステムの階層ディレクトリ構造に似た階層的なキー空間を形成します。

エンティティを識別する完全なキーは、エンティティの祖先パスから始まってそのエンティティ自身で終わる一連の種類と識別子のペアで構成されています。Key クラスのコンストラクタ メソッドは、このような連続的な種類 / ID を受け入れ、対象のエンティティのキーを示すオブジェクトを返します。

以下の例は、リビジョンごとにメッセージを保存するブログサービスです。メッセージはアカウントごとに、リビジョンはメッセージごとにそれぞれまとめられます。

class Revision(ndb.Model):
    message_text = ndb.StringProperty()
...
ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1')
ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '2')
ndb.Key('Account', 'larry@example.com', 'Message', 456, 'Revision', '1')
ndb.Key('Account', 'larry@example.com', 'Message', 789, 'Revision', '2')

このサンプルで、('Account', 'sandy@example.com')('Message', 123)('Revision', '1') はすべてキー / 識別子のペアです。

Message はモデルクラスではないことに注意してください。データを保存するのではなく、リビジョンをグループ化する方法としてのみ使用されます。

次のサンプルコードに示されているように、エンティティの種類はリスト内の最後の種類 / 名前のペアである。ndb.Key('Revision', '1')

名前付きパラメータを使用する

名前付きパラメータ parent を使用して、祖先パスのエンティティを直接指定できます。以下の表記はすべて同じキーを表しています。

ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1')

ndb.Key('Revision', '1', parent=ndb.Key(
    'Account', 'sandy@example.com', 'Message', 123))

ndb.Key('Revision', '1', parent=ndb.Key(
    'Message', 123, parent=ndb.Key('Account', 'sandy@example.com')))

ルート エンティティを指定する

ルート エンティティの場合は祖先パスが空で、エンティティ自身の種類と識別子だけでキーが構成されています。

sandy_key = ndb.Key(Account, 'sandy@example.com')

祖先を使用してエンティティを指定する

親キーを使用して新しいメッセージを挿入するには:

account_key = ndb.Key(Account, 'sandy@example.com')

# Ask Datastore to allocate an ID.
new_id = ndb.Model.allocate_ids(size=1, parent=account_key)[0]

# Datastore returns us an integer ID that we can use to create the message
# key
message_key = ndb.Key('Message', new_id, parent=account_key)

# Now we can put the message into Datastore
initial_revision = Revision(
    message_text='Hello', id='1', parent=message_key)
initial_revision.put()

親付きで作成したキーの場合、parent() メソッドは親エンティティを表すキーを返します。

message_key = initial_revision.key.parent()

数値キー ID を使用する

ID を指定せずにエンティティを作成できます。この場合、Datastore が数値 ID を自動的に生成します。一部の ID を選択し、一部の ID を Datastore で自動生成すると、一意キーの要件に違反する場合があります。ID を選択する番号の範囲を予約するか、文字列 ID を使用すると、この問題を回避できます。

ID の範囲を予約するには、モデルクラスの allocate_ids() クラスメソッドを使用します。

  • 指定した数の ID を割り当てます。
  • 指定の最大値まで ID をすべて割り当てます。

ID を割り当てる

特定のモデルクラス MyModel に 100 個の ID を割り当てるには:

first, last = MyModel.allocate_ids(100)

親キー p を持つエンティティに 100 個の ID を割り当てるには:

first, last = MyModel.allocate_ids(100, parent=p)

割り当てられた最初の ID と最後の ID がそれぞれ firstlast に返されます。これらの値を使用して、次のようにキーを作成します。

keys = [ndb.Key(MyModel, id) for id in range(first, last+1)]

このキーは、データストアの内部 ID ジェネレーターが以前に返したキーとは一致せず、将来的に内部 ID ジェネレーターの呼び出しによって返されるキーにもなりません。ただし、allocate_ids() メソッドは、返された ID がデータストアに存在するかどうかをチェックしません。ID ジェネレーターと情報を交換するだけです。

指定の最大値まで ID をすべて割り当てるには:

first, last = MyModel.allocate_ids(max=N)

このフォームにより、N 以下のすべての ID が割り当てられたものとみなされます。返された firstlast は、この操作で予約された ID の範囲を表します。割り当て済みの ID を予約してもエラーになりませんが、その場合、first は未割り当ての最初の ID を表し、last は最後に割り当てられた ID を表します。