Model クラス

注: 新しいアプリケーションを作成する際は、NDB クライアント ライブラリを使用することを強くおすすめします。NDB クライアント ライブラリには、Memcache API によるエンティティの自動キャッシュをはじめ、このクライアント ライブラリにはないメリットがあります。古い DB クライアント ライブラリを現在使用している場合は、DB から NDB への移行ガイドをお読みください。

Model クラスは、データモデル定義のスーパークラスです。

Model は、google.appengine.ext.db モジュールで定義されます。

はじめに

アプリケーションでデータモデルを定義するには、Model をサブクラス化するクラスを定義します。モデルのプロパティは、クラス属性と Property クラスのインスタンスを使用して定義します。例:

class Story(db.Model):
  title = db.StringProperty()
  body = db.TextProperty()
  created = db.DateTimeProperty(auto_now_add=True)

アプリケーションで新しいデータ エンティティを作成するには、Model クラスのサブクラスをインスタンス化します。エンティティのプロパティは、インスタンスの属性を使用して割り当てることも、コンストラクタへのキーワード引数として割り当てることもできます。

s = Story()
s.title = "The Three Little Pigs"

s = Story(title="The Three Little Pigs")

Model サブクラスの名前は、Datastore エンティティの種類名として使用されます。アンダースコア(__)2 つで始まる種類名は Datastore で予約されています。このような名前は Model サブクラスで使用しないでください。

属性の名前は、エンティティに設定された対応するプロパティの名前として使用されます。モデル インスタンスの属性のうち、名前がアンダースコア(_)で始まる属性は無視されます。そのため、データストアに保存されないデータについては、モデル インスタンスでこのような属性を使用して保管できます。

Datastore および Model クラスの API には、プロパティ名とモデル インスタンス属性に関するいくつかの制約事項があります。詳細については、使用できないプロパティ名をご覧ください。

すべてのエンティティにはキーがあります。キーは、そのエンティティの固有識別子です。オプションで、特定の種類のすべてのエンティティで一意の文字列として、キー名をキーに含めることもできます。エンティティの種類とキー名は、Key.from_path() メソッドと Model.get_by_key_name() メソッドでエンティティを取得するために使用できます。

また、エンティティには任意のエンティティを指定することもできます。親子関係によって形成されるエンティティ グループを使用して、Datastore 内でのトランザクション性とデータの局所性を制御します。アプリケーションで 2 つのエンティティの間に親子関係を作成するには、親エンティティを parent 引数として子エンティティのコンストラクタに渡します。

Model.get_or_insert() メソッドを使用してエンティティを取得すると、対象のエンティティが存在しない場合には必要に応じて Datastore 内にエンティティを作成できます。

keyname = "some_key"
s = Story.get_or_insert(keyname, title="The Three Little Pigs")

注: モデル インスタンスを明示的に、または Model.get_or_insert() によって初めて書き込む(put)までは、Datastore 内にモデル インスタンスに対応するエンティティは存在しません。

dict というモデル インスタンスのデータのコピーを作成するには、db.to_dict 関数を使用します。

コンストラクタ

Model クラスのコンストラクタは、次のように定義されます。

class Model (parent=None, key_name=None, **kwds)

これが、データモデル定義のスーパークラスです。

コンストラクタの実行中に、各プロパティの validate() メソッドが呼び出されます。これらの呼び出しで発生した例外は、このコンストラクタの呼び出し側に伝播されます。

引数

parent
新しいエンティティの親となるモデル インスタンスまたはエンティティのキー。
key_name

エンティティのキー名。この名前は主キーの一部となります。None の場合、システムが生成した数値 ID がキーに使用されます。

key_name の値は __*__ の形式にすることはできません。

キー名は、str の値を ASCII テキストに変換した状態の Unicode 文字列として保存されます。

このオブジェクトに対して put() を呼び出すと、同じキーが設定された既存の Datastore エンティティが上書きされます。

kwds
キーワード引数として使用するインスタンス プロパティの初期値。それぞれの名前が Model クラスで定義されている属性に対応します。

その他のキーワード属性

key

エンティティの明示的な Key インスタンス。key_nameparent と一緒には使用できません。None の場合、key_nameparent の動作にフォールバックします。allocate_ids() を使用して新しいエンティティの数値 ID を予約する場合に便利です。

key の値は有効な Key インスタンスでなければなりません。

このオブジェクトに対して put() を呼び出すと、同じキーが設定された既存の Datastore エンティティが上書きされます。

クラスメソッド

Model クラスには次のクラスメソッドがあります。

Model.get (keys)

指定されたキー(複数可)のモデル インスタンスを取得します。キーは、モデルの種類のエンティティを表すものでなければなりません。適切な種類のキーを指定しないと、KindError 例外が発生します。

このメソッドは db.get() 関数と同様ですが、型チェックが追加で行われます。

引数

keys
取得するエンティティのキー、キーの文字列表現、またはキーあるいはキーの文字列表現のリスト。
read_policy
目的のデータ整合性レベルを指定する読み取りポリシー
STRONG_CONSISTENCY
最新の結果を保証します。ただし、単一のエンティティ グループに限定されます。
EVENTUAL_CONSISTENCY
複数のエンティティ グループにわたる読み取りが可能ですが、返される結果は最新のものではないことがあります。一般に、結果整合性クエリのほうが強整合性クエリよりも処理時間が短くなりますが、その保証はありません。

注: グローバル(非祖先)クエリでは、この引数は無視されます。

deadline
Datastore から結果が返されるのを待機する時間の最大値(秒)。この時間を過ぎると処理を中止し、エラーを返します。整数値または浮動小数点値のいずれかを指定できます。デフォルト値(60 秒)を超える値は設定できませんが、デフォルトより短い値に設定することは可能です。これにより、特定のオペレーションが失敗と判定されるまでの時間を短くできます(ユーザーへのレスポンスの迅速化、オペレーションの再試行、別のオペレーションの試行、タスクキューへのオペレーションの追加などの目的に利用できます)。

keys が単一のキー(またはキーの文字列表現)からなる場合、該当するキーが Datastore 内にあれば、このメソッドはそのキーに関連付けられているモデル インスタンスを返します。ない場合は、None を返します。keys がリストの場合、戻り値は対応するモデル インスタンスのリストとなります。指定されたキーに関連付けられているエンティティがなければ、None 値のリストを返します。

db.get() 関数もご覧ください。

Model.get_by_id (ids, parent=None)

指定された数値 ID(複数可)のモデル インスタンスを取得します。

引数

ids
数値のエンティティ ID、または数値 ID のリスト。
parent
リクエストされたエンティティの親エンティティ(モデルまたはキー)。リクエストされたエンティティに親がない場合は None(デフォルト)。1 つの呼び出しで複数のエンティティをリクエストする場合、それらのエンティティの親がすべて同じでなければなりません。
read_policy
目的のデータ整合性レベルを指定する読み取りポリシー
STRONG_CONSISTENCY
最新の結果を保証します。ただし、単一のエンティティ グループに限定されます。
EVENTUAL_CONSISTENCY
複数のエンティティ グループにわたる読み取りが可能ですが、返される結果は最新のものではないことがあります。一般に、結果整合性クエリのほうが強整合性クエリよりも処理時間が短くなりますが、その保証はありません。

注: グローバル(非祖先)クエリでは、この引数は無視されます。

deadline
Datastore から結果が返されるのを待機する時間の最大値(秒)。この時間を過ぎると処理を中止し、エラーを返します。整数値または浮動小数点値のいずれかを指定できます。デフォルト値(60 秒)を超える値は設定できませんが、デフォルトより短い値に設定することは可能です。これにより、特定のオペレーションが失敗と判定されるまでの時間を短くできます(ユーザーへのレスポンスの迅速化、オペレーションの再試行、別のオペレーションの試行、タスクキューへのオペレーションの追加などの目的に利用できます)。

ids が単一の数値 ID からなる場合、該当する ID が Datastore 内にあれば、このメソッドはその ID に関連付けられているモデル インスタンスを返します。ない場合は、None を返します。ids がリストの場合、戻り値は対応するモデル インスタンスのリストとなります。指定された数値 ID に関連付けられているエンティティがなければ、None 値のリストを返します。

Model.get_by_key_name (key_names, parent=None)

指定されたキー名(複数可)のモデル インスタンスを取得します。

引数

key_names
キー名、またはキー名のリスト。
parent
リクエストされたエンティティの親エンティティ(モデル インスタンスまたはキー)。リクエストされたエンティティに親がない場合は None(デフォルト)。1 つの呼び出しで複数のエンティティをリクエストする場合、それらのエンティティの親がすべて同じでなければなりません。
read_policy
目的のデータ整合性レベルを指定する読み取りポリシー
STRONG_CONSISTENCY
最新の結果を保証します。ただし、単一のエンティティ グループに限定されます。
EVENTUAL_CONSISTENCY
複数のエンティティ グループにわたる読み取りが可能ですが、返される結果は最新のものではないことがあります。一般に、結果整合性クエリのほうが強整合性クエリよりも処理時間が短くなりますが、その保証はありません。

注: グローバル(非祖先)クエリでは、この引数は無視されます。

deadline
Datastore から結果が返されるのを待機する時間の最大値(秒)。この時間を過ぎると処理を中止し、エラーを返します。整数値または浮動小数点値のいずれかを指定できます。デフォルト値(60 秒)を超える値は設定できませんが、デフォルトより短い値に設定することは可能です。これにより、特定のオペレーションが失敗と判定されるまでの時間を短くできます(ユーザーへのレスポンスの迅速化、オペレーションの再試行、別のオペレーションの試行、タスクキューへのオペレーションの追加などの目的に利用できます)。

key_names が単一のキー名からなる場合、該当するキー名が Datastore 内にあれば、このメソッドはそのキー名に関連付けられているモデル インスタンスを返します。ない場合は、None を返します。key_names がリストの場合、戻り値は対応するモデル インスタンスのリストとなります。指定されたキー名に関連付けられているエンティティがなければ、None 値のリストを返します。

Model.get_or_insert (key_name, **kwds)

指定されたキー名が設定されているモデルの種類のエンティティを取得しようと試みます。該当するエンティティが存在する場合、get_or_insert() は単純にそのエンティティを返します。存在しない場合は、kwds に指定された種類、名前、パラメータの新しいエンティティを作成し、保存して返します。

アトミック性を確保するために、get 操作と以降の(可能な場合)put 操作はトランザクションにラップされます。つまり、get_or_insert() は既存のエンティティを上書きすることはありません。指定された種類と名前が設定されたエンティティが存在しない場合に限り、新しいエンティティを挿入します。get_or_insert() は次の Python コードと同じとも言えます。

def txn(key_name, **kwds):
  entity = Story.get_by_key_name(key_name, parent=kwds.get('parent'))
  if entity is None:
    entity = Story(key_name=key_name, **kwds)
    entity.put()
  return entity

def get_or_insert(key_name, **kwargs):
  return db.run_in_transaction(txn, key_name, **kwargs)

get_or_insert('some key', title="The Three Little Pigs")

引数

key_name
エンティティのキーの名前。
kwds
指定されたキー名のインスタンスが存在しない場合に Model クラスのコンストラクタに渡すキーワード引数。対象のエンティティに親エンティティがある場合、parent 引数は必須です。

注: get_or_insert()read_policy 引数や deadline 引数を受け入れません。

このメソッドが返す、リクエストされたエンティティを表す Model クラスのインスタンスは、既存のものである場合も、メソッドが作成したものである場合もあります。すべての Datastore 操作の例に漏れず、このメソッドがトランザクションを完了できなかった場合は TransactionFailedError が発生します。

Model.all (keys_only=False)

該当するモデルに対応する種類のすべてのエンティティを表す Query オブジェクトを返します。クエリ オブジェクトに対して実行するメソッドでは、クエリの実行前にフィルタと並べ替え順を適用できます。詳細については、Query クラスのページをご覧ください。

引数

keys_only
クエリでエンティティ全体を返すか、またはキーだけを返すかどうか。クエリでキーだけを返すほうが、エンティティ全体を返す場合より処理時間が短く、CPU 時間を短縮できます
Model.gql (query_string, *args, **kwds)

このモデルの全インスタンスを対象に GQL クエリを実行します。

引数

query_string
GQL クエリの SELECT * FROM model(このクラスメソッドを使用することによって暗黙に定義されます)に続く部分。
args
位置パラメータ バインディング。GqlQuery() コンストラクタと同様です。
kwds
キーワード パラメータ バインディング。GqlQuery() コンストラクタと同様です。
s = Story.gql("WHERE title = :1", "Little Red Riding Hood")

s = Story.gql("WHERE title = :title", title="Little Red Riding Hood")

戻り値は GqlQuery オブジェクトです。このオブジェクトを使用して結果にアクセスできます。

Model.kind ()
モデルの種類を返します。これは通常、Model サブクラスの名前です。
Model.properties ()
この Model クラスに定義されたすべてのプロパティのディクショナリを返します。

インスタンス メソッド

モデル インスタンスには次のメソッドがあります。

key ()

このモデル インスタンスの Datastore Key を返します。

モデル インスタンスのキーには、インスタンスのエンティティの種類と一意の識別子が含まれます。識別子は、インスタンスの作成時にアプリケーションで明示的に割り当てたキー名の文字列か、またはインスタンスが Datastore に書き込まれた(put)時点で App Engine により自動的に割り当てられた整数の数値 ID のいずれかです。インスタンスに ID が割り当てられる前に key() を呼び出すと、NotSavedError 例外が発生します。

put ()

モデル インスタンスをデータストアに格納します。モデル インスタンスが新しく作成されてデータストアにまだ格納されていない場合、このメソッドにより、データストア内に新しいデータ エンティティが作成されます。それ以外の場合は、該当する既存のデータ エンティティが現在のプロパティ値で更新されます。

このメソッドは、格納されているエンティティのキーを返します。

データをコミットできなかった場合は、 TransactionFailedError 例外が発生します。

引数

deadline
Datastore から結果が返されるのを待機する時間の最大値(秒)。この時間を過ぎると処理を中止し、エラーを返します。整数値または浮動小数点値のいずれかを指定できます。デフォルト値(60 秒)を超える値は設定できませんが、デフォルトより短い値に設定することは可能です。これにより、特定のオペレーションが失敗と判定されるまでの時間を短くできます(ユーザーへのレスポンスの迅速化、オペレーションの再試行、別のオペレーションの試行、タスクキューへのオペレーションの追加などの目的に利用できます)。
delete ()

Datastore からモデル インスタンスを削除します。インスタンスが一度も Datastore に書き込まれていない場合(put)、削除操作によって NotSavedError 例外が発生します。

引数

deadline
Datastore から結果が返されるのを待機する時間の最大値(秒)。この時間を過ぎると処理を中止し、エラーを返します。整数値または浮動小数点値のいずれかを指定できます。デフォルト値(60 秒)を超える値は設定できませんが、デフォルトより短い値に設定することは可能です。これにより、特定のオペレーションが失敗と判定されるまでの時間を短くできます(ユーザーへのレスポンスの迅速化、オペレーションの再試行、別のオペレーションの試行、タスクキューへのオペレーションの追加などの目的に利用できます)。
is_saved ()

モデル インスタンスが一度でも Datastore に書き込まれている場合(put)、True を返します。

このメソッドは、インスタンスが作成されてから 1 回以上 Datastore に書き込まれているかどうかだけをチェックします。前回の書き込み以降にインスタンスのプロパティが更新されていかどうかはチェックしません

dynamic_properties ()

このモデル インスタンスに定義されているすべての動的プロパティの名前のリストを返します。このメソッドが適用されるのは、Expando クラスのインスタンスのみです。Expando 以外のモデル インスタンスに対しては、空のリストが返されます。

parent ()

このインスタンスの親エンティティのモデル インスタンスを返します。このインスタンスに親がない場合は None を返します。

parent_key ()

このインスタンスの親エンティティの Key を返します。このインスタンスに親がない場合は、None を返します。

to_xml ()

モデル インスタンスの XML 表現を返します。

プロパティ値は Atom 仕様と Data 仕様に準拠します。

使用できないプロパティ名

Datastore とその API には、エンティティのプロパティおよびモデル インスタンスの属性に関するいくつかの制約事項があります。

最初と最後がアンダースコア 2 つのプロパティ名(__*__)は、すべて Datastore で予約されています。Datastore エンティティでそのような名前のプロパティを使用することはできません。

Python モデル API は、Model クラスまたは Expando クラスの、名前がアンダースコア(_)で始まる属性をすべて無視します。アプリケーションでは、このような属性を使用して、Datastore に保存されないデータをモデル オブジェクトに関連付けることができます。

最後に、Python モデル API ではオブジェクト属性を使用してモデルのプロパティを定義します。デフォルトでは、これらのオブジェクト属性に基づく名前が Datastore エンティティのプロパティに付けられます。Model クラスには他の目的に使用するプロパティやメソッドがあるため、それらの属性を Python API でプロパティに使用することはできません。たとえば、Model クラスでは、key 属性でアクセスするプロパティを使用できません。

ただし、プロパティ コンストラクタに name 引数を渡すことにより、プロパティは Datastore 用に属性名とは異なる名前を指定できます。これにより、Datastore エンティティは、Model クラスの予約済み属性と同様のプロパティ名を持ち、クラス内では別の属性名を使用できます。

class MyModel(db.Model):
  obj_key = db.StringProperty(name="key")

Python API の Model クラスで予約されている属性名は次のとおりです。

  • all
  • app
  • copy
  • delete
  • entity
  • entity_type
  • fields
  • from_entity
  • get
  • gql
  • instance_properties
  • is_saved
  • key
  • key_name
  • kind
  • parent
  • parent_key
  • properties
  • put
  • setdefault
  • to_xml
  • update