Amazon

ラベル gql の投稿を表示しています。 すべての投稿を表示
ラベル gql の投稿を表示しています。 すべての投稿を表示

2011年3月30日水曜日

GQLのLIMIT, OFFSETではバウンドパラメータは無効

2011/3/30現在:
GQLのLIMITおよびOFFSETではバウンドパラメータによる指定は無効となる。

LIMIT_MAX=3
SomeModel.gql("WHERE ID=:1 LIMIT :2", id, LIMIT_MAX)
を指定すると
Parse Error: Non-number limit in LIMIT clause at symbol :2
となる。


Google App Engineのディスカッションでは確かにこの議論がされているが
comment3:LIMIT and OFFSET don't currently support bound parameters.
 
ドキュメント読むあたり書いてないんだよね。。。 

2011年3月21日月曜日

GQLの注意点(まとめ)

  • StringPropertyは500バイト未満まで、それ以上はTextProperty
  • リクエスト1 つのクエリに対して最大 1,000 件の結果
  • IN と != の各演算子は、背後で複数のクエリを使用します。たとえば IN 演算子は、リスト内のどのアイテムについても、基礎となるデータストア クエリを個別に実行します。返されたエンティティは、すべての基礎となるデータストア クエリのクロス積の結果であり、重複が除去されます。1 つの GQL クエリに最大 30 のデータストア クエリが許可されます。(超えた場合はrc=504 errorを返す)
  • 静的 ListProperty には、空のリストを値として割り当てることができます。このプロパティはデータストアには存在しませんが、モデル インスタンスの動作は値が空のリストである場合と同じです。静的 ListProperty は、None の値を持つことはできません。
  • list 値を持つ動的プロパティには、空のリスト値を割り当てることはできません。ただし、この動的プロパティは None の値を持つことができるほか、del を使用して削除することもできます。
  •  
- 制限
最大エンティティ サイズ 1 MB
エンティティのインデックス値の最大数 (1) 1、000 個
バッチ put または delete の最大エンティティ数 500 エンティティ
バッチ get の最大エンティティ数 1,000 エンティティ
クエリの最大結果オフセット 1,000

GAE上のデータストアからデータを消す方法

GAEからデータを削除する方法は公式ドキュメントによれば以下の方法で削除できる。

q = db.GqlQuery("SELECT * FROM Message WHERE create_date < :1", earliest_date)
results = q.fetch(10)
for result in results:
  result.delete()

# or...

q = db.GqlQuery("SELECT * FROM Message WHERE create_date < :1", earliest_date)
results = q.fetch(10)
db.delete(results)


但し、GQLには以下の制限があって、保存してあるデータ量が多いと消えない可能性がある。
  • 一定時間内にリクエストを返すべし
  • 一度に取り出せる量が1000件まで
  • 使えるリソースの上限を超えた
そこでこちらのサイトを参考にしながら、制限を超えないように一回で100件消すリクエストを発行するpythonのスクリプトを作り、全部消えるまで自動でリロードするようにする。
getMyData, getMyURLを自分のGAEデータモデルに変更すること。

from google.appengine.ext import webapp
from google.appengine.ext import db
from google.appengine.ext.webapp.util import run_wsgi_app


class MyData1(db.Model):
    pass

class MyData2(db.Model):
    pass


class AbstractRemoveAll(webapp.RequestHandler):

    def get(self) :

        #limit = 50
        limit = 100
        list  = self.getMyList(limit)

    if list==None :
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.out.write( 'Error.' )
            return 

        if len(list)<1:
            self.response.headers['Content-Type'] = 'text/plain'
            self.response.out.write( 'OK remove all data.' )
            return 


        for c in list:
            c.delete()

        self.response.headers['Content-Type'] = 'text/html'
        self.response.out.write( '<html>' )
        self.response.out.write( '<head>' )
        self.response.out.write( '<META HTTP-EQUIV="REFRESH" CONTENT="10;URL='+self.getMyUrl()+'">')
        self.response.out.write( '</head>' )
        self.response.out.write( '<body>' )
        self.response.out.write( '<p>' )
        self.response.out.write( len(list) )
        self.response.out.write( '</p>' )
        self.response.out.write( 'Again after 10seconds.' )
        self.response.out.write( '</body>' )
        self.response.out.write( '</html>' )


    def getMyUrl(self) :
        return '/RemoveAll'

    def getMyList(self,limit):
        return []


class RemoveAll1(AbstractRemoveAll):
    def getMyUrl(self) :
        return '/RemoveAll1'

    def getMyList(self,limit):
        q=MyData1.gql('LIMIT '+str(limit))
    return q[0:min(q.count(),limit)]

class RemoveAll2(AbstractRemoveAll):
    def getMyUrl(self) :
        return '/RemoveAll2'

    def getMyList(self,limit):
        q=MyData2.gql('LIMIT '+str(limit))
    return q[0:min(q.count(),limit)]



application = webapp.WSGIApplication(
    [
        ('/RemoveAll2', RemoveAllPage2),
        ('/RemoveAll1', RemoveAllPage1)
    ],
    debug=True)


def main(): 
    run_wsgi_app(application)

if __name__ == "__main__": 
    main()

2011年3月10日木曜日

GAEのgqlでIN演算子を使う

GAEのGQLのリファレンスによれば 
"IN 演算子は、プロパティの値とリスト内の各アイテムを比較します。IN 演算子は、各値に 1 つのクエリが OR 演算された多数の = クエリに相当します。このクエリでは、指定されたプロパティの値がリスト内の値と同じであるエンティティが返されます。"

friendInfo = ["f0001","f0002"]
someFriend = FriendModel.gql('WHERE friend IN :1",friendInfo)

という感じでFriendModel内のfriendプロパティ値がfriendInfoにあるアイテムの値("f0001","f0002")であるときに抽出してくる。

とても使いやすいのだけど、この比較するアイテムリストを空にした場合はどうなるか?
直感的には何もヒットしないのが正解と思うのだけど、
実際のところは全部がヒットする。つまり、この場合はWHERE句がないのと同じようです。
someFriend = FriendModel.gql('WHERE friend IN :1 AND gender=:2",friendInfo,gender)
だと、friend IN friendInfoは無視されて、gender=genderの条件だけ適用されるみたい。
なんだか変な感じ。
自分の環境では、このIN演算子は無視されるよう。

Amazon3