GqlQuery クラス

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

クラス GqlQuery は、SQL に似た App Engine クエリ言語 GQL を使用して App Engine Datastore からエンティティを取得するクエリを表します。GQL のすべての構文と機能の説明は、GQL リファレンスをご覧ください。また、関連するクラス Query もご覧ください。このクラスは、GQL の代わりにオブジェクトとメソッドを使用してクエリを整えます。

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

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

はじめに

アプリケーションでは、GqlQuery コンストラクタを直接呼び出すか、エンティティの種類のモデルクラスのクラスメソッド gql() を呼び出して GQL クエリ オブジェクトを作成します。GqlQuery コンストラクタは、引数にクエリ文字列(「SELECT ... FROM model-name」で始まる完全な GQL ステートメント)を取ります。WHERE 句の値は、数値や文字列のリテラルです。パラメータで値をバインドすることもできます。パラメータは、位置引数またはキーワード引数でバインドできます。

q = GqlQuery("SELECT * FROM Song WHERE composer = 'Lennon, John'")

q = GqlQuery("SELECT __key__ FROM Song WHERE composer = :1", "Lennon, John")

q = GqlQuery("SELECT * FROM Song WHERE composer = :composer", composer="Lennon, John")

使いやすくするため、Model クラスと Expando クラスには、GqlQuery インスタンスを返すクラスメソッド gql() が用意されています。このメソッドは GQL クエリ文字列を受け取りますが、先頭に「SELECT ... FROM model-name」を付ける必要はありません。

q = Song.gql("WHERE composer = 'Lennon, John'")

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

  • クエリ オブジェクトをイテラブルとして扱い、一致するエンティティを 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() の使用をおすすめします。

コンストラクタ

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

class GqlQuery (query_string, *args, **kwds)

GQL クエリ言語を使用して App Engine Datastore からエンティティを取得するため、クラス GqlQuery のインスタンスを作成します。

引数

query_string
完全な GQL ステートメントを含む文字列。
args
位置パラメータの値。
kwds
キーワード パラメータの値。

インスタンス メソッド

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

bind (*args, **kwds)

クエリのパラメータ値を再バインドします。パラメータの再バインド後に最初に結果にアクセスすると、変更されたクエリが実行されます。

パラメータを既存の GqlQuery オブジェクトに再バインドすると、クエリ文字列の再解析が不要なため、新しい GqlQuery オブジェクトを作成するより処理時間が短くなります。

引数

args
位置パラメータの新しい値。
kwds
キーワード パラメータの新しい値。
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
返される結果の最大数。このパラメータを省略すると、GQL クエリ文字列の 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 を返します。最大で 1 件の結果が Datastore から取得されます。GQL クエリ文字列の LIMIT 句(指定されている場合)は無視されます。

引数

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
カウントされる結果の最大数。

注: 明示的に指定した場合、このパラメータは、GQL クエリ文字列の LIMIT 句で指定されたどの値よりも優先されます。ただし、このパラメータを省略した場合、デフォルト値(1000)が GQL クエリの LIMIT 句より優先されることはありません。このデフォルト値は、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.GqlQuery(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 でエンコードされたカーソル文字列。