Query クラス

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

Query クラスは、App Engine データストアからエンティティを取得するクエリを表します(関連する GqlQuery クラスについてもご覧ください。これは、SQL に似たクエリ言語である GQL を使用してクエリを定義します)。

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

注: インデックス ベースのクエリ メカニズムはさまざまなクエリをサポートしているため、ほとんどのアプリケーションに適しています。ただし、他のデータベース テクノロジーで一般にサポートされているいくつかの種類のクエリがサポートされていません。具体的には、結合クエリおよび集計クエリは Datastore のクエリエンジン内でサポートされていません。Datastore クエリの制限については、Datastore クエリのページをご覧ください。

はじめに

アプリケーションでは、Query コンストラクタを直接呼び出すことで、特定の種類のエンティティに対するクエリ オブジェクトを作成します。

class Song(db.Model):
  title = db.StringProperty()
  composer = db.StringProperty()
  date = db.DateTimeProperty()

q = db.Query(Song)

あるいは、その種類のモデルクラスのクラスメソッド all() を使用します。

q = Song.all()

Query クラスの結果インスタンスは、これ以上変更することなく、指定された種類の既存エンティティをすべて取得します。続いてオブジェクトのメソッド呼び出しを使用することで、追加のフィルタ条件、祖先条件、並べ替え順序を指定してクエリをカスタマイズできます。

q.filter('title =', 'Imagine')
q.ancestor(ancestor_key)
q.order('-date')

これらのメソッドはすべてクエリ オブジェクト自体を返すため、1 つのステートメントにカスケードできます。

q.filter('title =', 'Imagine').ancestor(key).order('-date')

アプリケーションはその後、次のいずれかの方法で、クエリを実行して結果にアクセスできます。

  • クエリ オブジェクトをイテラブルとして扱い、一致するエンティティを 1 つずつ処理する。

    for song in q:
      print song.title

    これは、クエリの run() メソッドを暗黙的に呼び出し、一致するエンティティを生成します。したがって、次に示すコードと同じになります。

    for song in q.run():
      print song.title

    キーワード引数 limit を使用して、処理する結果の数を制限できます。

    for song in q.run(limit=5):
      print song.title

    イテレータ インターフェースは結果をキャッシュしないので、クエリ オブジェクトから新しいイテレータを作成すると、同じクエリが最初から反復されます。

  • クエリの get() メソッドを呼び出し、Datastore で最初に検出された一致エンティティを 1 つ取得する。

    song = q.get()
    print song.title
  • クエリの fetch() メソッドを呼び出し、指定した結果件数を上限として、一致するすべてのエンティティのリストを取得する。

    results = q.fetch(limit=5)
    for song in results:
      print song.title

    run() と同様に、クエリ オブジェクトは結果をキャッシュしないので、次に fetch() を呼び出すと、同じクエリが再実行されます。

    注: このメソッドを使用しなければならないケースは、めったにありません。ほとんどの場合で、このメソッドではなく run() の使用をおすすめします。

コンストラクタ

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

class Query (model_class=None, keys_only=False, cursor=None, namespace=None, projection=None, distinct=False)

App Engine Datastore からエンティティを取得するために、Query クラスのインスタンスを作成します。

作成されたクエリ オブジェクトは、これ以上変更することなく、model_class で指定された種類の既存エンティティをすべて取得します。続いて、filter()ancestor(),order() インスタンス メソッドを使用し、追加のフィルタ条件、祖先条件、並べ替え順序を指定してクエリをカスタマイズできます。

引数

model_class
クエリが適用されるエンティティの種類を表す Model(または Expando)クラス。
keys_only
true の場合、完全なエンティティではなく、キーだけを返します。キーのみのクエリは、エンティティ全体を返すクエリよりも迅速かつ低コストで実行できます。
cursor
クエリを再開するカーソル位置。
namespace
クエリで使用する名前空間。
projection
返されるプロパティ名のリストまたはタプル。指定したプロパティを処理しているエンティティだけが返されます。指定しない場合は、デフォルトでエンティティ全体が返されます。射影クエリは、エンティティ全体を返すクエリよりも迅速かつ低コストで実行できます。

注: このパラメータを指定すると、クエリのインデックスの要件が変わることがあります。

distinct
射影クエリの場合、distinct=True と指定すると、完全に一意の結果のみが結果セットで返されます。つまり、射影されているプロパティについて同じ値を持つエンティティが複数存在する場合は、最初の結果だけが返されます。
True
projection で指定されたプロパティの値のセットごとに、最初の結果のみが返されます。
False
すべての結果が返されます。

インスタンス メソッド

Query クラスのインスタンスには次のメソッドがあります。

filter (property_operator, value)

クエリにプロパティ フィルタを追加します。クエリは、プロパティがすべてのフィルタ条件を満たすエンティティだけを返します。

引数

property_operator
プロパティ名とオプションの比較演算子(=!=<<=>>=IN)から構成される文字列。'age >' のようにスペースで区切ります。比較演算子を使用せずにプロパティ名だけを指定すると、デフォルトで等価性(=)が比較されます。
value
プロパティ値と比較する値。次に例を示します。

q.filter('height >', 42).filter('city =', 'Seattle')
q.filter('user =', users.get_current_user())

比較されるプロパティと同じ値タイプを比較値に指定する必要があります。

ancestor (ancestor)

クエリに祖先フィルタを追加します。クエリは、指定した祖先のエンティティのみを返します。

引数

ancestor
祖先エンティティまたはキー。
order (property)

クエリに並べ替え順を追加します。複数の並べ替え順を追加すると、指定した順番で適用されます。

引数

プロパティ
並べ替えるプロパティの名前の文字列。先頭にハイフン(-)を付けると、降順になります。ハイフンを省略すると、昇順(デフォルト)になります。次に例を示します。
# Order alphabetically by last name:
q.order('last_name')

# Order by height, tallest to shortest:
q.order('-height')
projection ()

projection 内のプロパティのタプル、または None を返します。

is_keys_only ()

キーのみのクエリであるかどうかを示すブール値を返します。

run (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, limit=None, batch_size=20, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

クエリの結果をループするためのイテラブルを返します。このメソッドにより、次のように、クエリの操作をパラメータ設定で指定して、結果に繰り返しアクセスできます。

  1. offset 引数で指定された数の結果を取得して破棄します。
  2. limit 引数で指定された数を最大として結果を取得して返します。

したがって、メソッドのパフォーマンスは、offsetlimit の合計に比例して変化します。取得する結果の数がわかっている場合は、明示的な値を limit に設定する必要があります。

このメソッドでは、パフォーマンス向上のために非同期プリフェッチを使用します。デフォルトでは、データストアから少量ずつ結果を取得します。これによりアプリケーションは、イテレーションを停止して、必要数を超える結果を取得しないようにできます。

ヒント: 結果の数がわからない場合に、利用可能なすべての結果を取得するには、batch_size に大きな値(1000 など)を設定します。

ヒント: 引数のデフォルト値を変更する必要がない場合は、クエリ オブジェクトのみを直接イテラブルとして使用して、ループを制御できます。その場合は、デフォルトの引数を使用して run() が暗黙的に呼び出されます。

引数

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

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

deadline
Datastore から結果が返されるのを待機する時間の最大値(秒)。この時間を過ぎると処理を中止し、エラーを返します。整数値または浮動小数点値のいずれかを指定できます。デフォルト値(60 秒)を超える値は設定できませんが、デフォルトより短い値に設定することは可能です。これにより、特定のオペレーションが失敗と判定されるまでの時間を短くすることができます(ユーザーへの応答の迅速化、オペレーションの再試行、別のオペレーションの試行、タスクキューへのオペレーションの追加などの目的に利用できます)。
offset
最初の結果を返すまでにスキップされる結果の数。
limit
返される結果の最大数。省略するか None に設定すると、デフォルトで、利用可能な結果をすべて取得します。
batch_size
1 回の一括処理で取得を試行する結果の数。limit が設定されている場合は、デフォルトは limit で指定されている値になります。それ以外の場合、デフォルトは 20 になります。
keys_only
true の場合、完全なエンティティではなく、キーだけを返します。キーのみのクエリは、エンティティ全体を返すクエリよりも迅速かつ低コストで実行できます。
projection
返されるプロパティ名のリストまたはタプル。指定したプロパティを処理しているエンティティだけが返されます。指定しない場合は、デフォルトでエンティティ全体が返されます。射影クエリは、エンティティ全体を返すクエリよりも迅速かつ低コストで実行できます。

注: このパラメータを指定すると、クエリのインデックスの要件が変わることがあります。

start_cursor
クエリを開始するカーソル位置。
end_cursor
クエリを終了するカーソル位置。
get (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

クエリを実行して最初の結果を返します。結果がない場合は None を返します。

引数

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

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

deadline
Datastore から結果が返されるのを待機する時間の最大値(秒)。この時間を過ぎると処理を中止し、エラーを返します。整数値または浮動小数点値のいずれかを指定できます。デフォルト値(60 秒)を超える値は設定できませんが、デフォルトより短い値に設定することは可能です。これにより、特定のオペレーションが失敗と判定されるまでの時間を短くすることができます(ユーザーへの応答の迅速化、オペレーションの再試行、別のオペレーションの試行、タスクキューへのオペレーションの追加などの目的に利用できます)。
offset
最初の結果を返すまでにスキップされる結果の数。
keys_only
true の場合、完全なエンティティではなく、キーだけを返します。キーのみのクエリは、エンティティ全体を返すクエリよりも迅速かつ低コストで実行できます。
projection
返されるプロパティ名のリストまたはタプル。指定したプロパティを処理しているエンティティだけが返されます。指定しない場合は、デフォルトでエンティティ全体が返されます。射影クエリは、エンティティ全体を返すクエリよりも迅速かつ低コストで実行できます。

注: このパラメータを指定すると、クエリのインデックスの要件が変わることがあります。

start_cursor
クエリを開始するカーソル位置。
end_cursor
クエリを終了するカーソル位置。
fetch (limit, read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, keys_only=False, projection=None, start_cursor=None, end_cursor=None)

クエリを実行して結果のリスト(空の可能性もあります)を返します。

  1. offset 引数で指定された数の結果を取得して破棄します。
  2. limit 引数で指定された数を最大として結果を取得して返します。

したがって、メソッドのパフォーマンスは、offsetlimit の合計に比例して変化します。

注: このメソッドは単に run() メソッドのシンラッパーにすぎません。run() を直接使用するより効率が悪く、メモリの消費も多くなります。fetch() を使用しなければならないケースはほとんどありません。このメソッドは主に、メモリ上にあるクエリ結果の全リストの取得が必要な場合に備えて用意されています。

ヒント: fetch() メソッドは、limit 引数で指定された数の結果のみを取得するように設計されています。結果の数がわからない場合に利用可能なすべての結果を取得するには、fetch() ではなく run() を使用します。その際、バッチサイズに大きな値(run(batch_size=1000) など)を指定します。

引数

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

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

deadline
Datastore から結果が返されるのを待機する時間の最大値(秒)。この時間を過ぎると処理を中止し、エラーを返します。整数値または浮動小数点値のいずれかを指定できます。デフォルト値(60 秒)を超える値は設定できませんが、デフォルトより短い値に設定することは可能です。これにより、特定のオペレーションが失敗と判定されるまでの時間を短くすることができます(ユーザーへの応答の迅速化、オペレーションの再試行、別のオペレーションの試行、タスクキューへのオペレーションの追加などの目的に利用できます)。
offset
最初の結果を返すまでにスキップされる結果の数。
keys_only
true の場合、完全なエンティティではなく、キーだけを返します。キーのみのクエリは、エンティティ全体を返すクエリよりも迅速かつ低コストで実行できます。
projection
返されるプロパティ名のリストまたはタプル。指定したプロパティを処理しているエンティティだけが返されます。指定しない場合は、デフォルトでエンティティ全体が返されます。射影クエリは、エンティティ全体を返すクエリよりも迅速かつ低コストで実行できます。

注: このパラメータを指定すると、クエリのインデックスの要件が変わることがあります。

start_cursor
クエリを開始するカーソル位置。
end_cursor
クエリを終了するカーソル位置。
count (read_policy=STRONG_CONSISTENCY, deadline=60, offset=0, limit=1000, start_cursor=None, end_cursor=None)

クエリに一致する結果の件数を返します。このメソッドは、実際に結果をすべて取得する場合と比較して一定の割合で速くなりますが、このメソッドにおいても実行時間は offsetlimit の合計に比例して変化します。結果の件数が少ないと予想される場合を除き、limit 引数の指定をおすすめします。この引数を指定しない場合は、件数のカウントが終了するか、メソッドがタイムアウトするまで処理が続行されます。

引数

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

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

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

プライマリ、複合、種類、シングル プロパティ インデックスなど、実行したクエリで使用されたインデックスのリストを返します。

注意: まだ実行されていないクエリでこのメソッドを呼び出すと、 AssertionError 例外が発生します。

注: この機能は、開発サーバーでは完全にはサポートされていません。開発サーバーで使用した場合、結果は、空のリストか、複合インデックスを 1 つのみ含んだリストのいずれかとなります。

たとえば、次に示すコードでは、クエリで使用されるインデックスの情報が出力されます。

# other imports ...
import webapp2
from google.appengine.api import users
from google.appengine.ext import db

class Greeting(db.Model):
  author = db.StringProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)

class MainPage(webapp2.RequestHandler):
  def get(self):
    user = users.get_current_user()
    q = db.Query(Greeting)
    q.filter("author =", user.user_id())
    q.order("-date")
    q.fetch(100)
    index_list = q.index_list()
    for ix in index_list:
      self.response.out.write("Kind: %s" % ix.kind())
      self.response.out.write("<br />")
      self.response.out.write("Has ancestor? %s" % ix.has_ancestor())
      self.response.out.write("<br />")
      for name, direction in ix.properties():
        self.response.out.write("Property name: "+name)
        self.response.out.write("<br />")
        if direction == db.Index.DESCENDING:
          self.response.out.write("Sort direction: DESCENDING")
        else:
          self.response.out.write("Sort direction: ASCENDING")
        self.response.out.write("<br />")

このコードにより、インデックスごとに次のような出力が生成されます。

Kind: Greeting
Has ancestor? False
Property name: author
Sort direction: ASCENDING
Property name: date
Sort direction: DESCENDING
cursor ()

取得した最後の結果に続いて、クエリの結果セット内での位置を示す、Base64 でエンコードされたカーソル文字列を返します。カーソル文字列は HTTP GET や HTTP POST パラメータで使用しても安全で、データストアや Memcache に格納することもできます。次回同じクエリを呼び出す際に、start_cursor パラメータか with_cursor() メソッドを使用してこの文字列を指定すると、その位置から結果の取得を再開できます。

注意: まだ実行されていないクエリでこのメソッドを呼び出すと、 AssertionError 例外が発生します。

注: 一部のクエリは cursor に対応していません。詳細については、Datastore クエリのページをご覧ください。

with_cursor (start_cursor, end_cursor=None)

クエリの結果セット内で取得を開始する位置と、取得を終了する位置(オプション)を指定します。開始位置および終了位置を示すカーソル文字列は、最後のクエリ実行後に cursor() を呼び出すことによって取得できます。現在のクエリでのエンティティの種類、プロパティ フィルタ、祖先フィルタ、並べ替え順序などは、前回実行したクエリと同一である必要があります。

引数

start_cursor
クエリの開始位置を示す、Base64 でエンコードされたカーソル文字列。
end_cursor
クエリの終了位置を示す、Base64 でエンコードされたカーソル文字列。