GAEのクエリクラスでのfetch()
いわゆる limit, offset の指定でちょっと詰まった→とりあえず解決した、のでメモ。
テストデータが100件入っているとする。うち、50件は「sale_price = 100」にマッチする、とする。
class Song(db.Model): title = db.StringProperty() composer = db.StringProperty() date = db.DateTimeProperty() sale_price = db.IntegerProperty() # test:1 song = Song.all().fetch(limit=3, offset=0) print len(song) # 結果 3 # test:2 song = Song.all() song.fetch(limit=3, offset=0) print len(song) # 結果 100 # test:3 song = Song.all() song_data = song.fetch(limit=3, offset=0) print len(song_data) # 結果 3 # test:4 song = Song.all().filter('safe_price = ', 100).fetch(limit=3, offset=0) print len(song) # 結果 3 # test:5 song = Song.all().filter('safe_price = ', 100) song.fetch(limit=3, offset=0) print len(song) # 結果 50 # test:6 song = Song.all().filter('safe_price = ', 100) song_data = song.fetch(limit=3, offset=0) print len(song_data) # 結果 3
ん?filter() と同じノリで書いてたら希望する結果が返ってこない。ドキュメントにある「データストアそのものによってスキップされません。」のことかしら?
limit および offset 引数はそれぞれ、データストアからフェッチする結果の数と fetch() メソッドによって返される結果の数をコントロールします。 * データストアが offset +limit の結果をフェッチし、アプリケーションに渡します。最初の offset 結果は、データストアそのものによってスキップ されません。 * fetch() メソッドが最初の offset 結果をスキップし、残り(limit 結果)を返します。 * クエリの性能特性は、offset 数 + limit と直線的に比例します。
上のコードだと、テストの 1,3,4,6 はこういう動作をしている。
- song に入る値(データストアから帰ってくる値)は、3件(limit)+0件(offset) → 3件。
- fetch() メソッドが 0件(offset) をスキップして 3件(limit) のデータを song_data へ入れている。
- 結果、件数を表示すると3件になる。
テストの 2,5 はこういう動作をしている。
- song に入る値(データストアから帰ってくる値)は、3件(limit)+0件(offset) → 3件。
- song に入っている件数を表示していることになるので、データストアからから取得された件数(100件, 50件)が表示される。
なので、こうなる。
# test:7 song = Song.all() print len(song.fetch(limit=3, offset=0)) # 結果 3
理解はこれであってるかな(・∀・)わーい
補足
fetch() で帰ってくるデータは List型でした。
# test:1 song = Song.all().fetch(limit=3, offset=0) print len(song) # 結果 3 print type(song) # <type 'list'>