GAE&数据存储 - 使用python过滤和删除实体

时间:2013-07-24 10:22:29

标签: python google-app-engine google-cloud-datastore gql

我正在尝试从数据存储表中删除type字段值等于“TEST”的所有实体。

实际上我的表结构是这样的:

表格测试

id    |    type    |    value    
---------------------------------
1     |   TEST     |    aksjdh
2     |   FOO      |    wer
3     |   TEST     |    gg
4     |   TEST     |    werqwer
5     |   BAR      |    akvcvcxjdh

我可以使用这段python代码删除所有实体,通过URL请求调用:

import cgi
import datetime
import urllib
import webapp2
from google.appengine.ext import db

class Test(db.Model):
    id = db.StringProperty()
    type = db.StringProperty()
    value = db.StringProperty()

class TestHandler(webapp2.RequestHandler):
    def get(self):
        ...
        db.delete(Test.all())

app = webapp2.WSGIApplication([
    ('/deleteTest', TestHandler)
], debug=True)

我想知道的是:在前面的代码中,为了删除所有Test的实体,我已经使用了Test类的方法all(),我是否必须使用相同的逻辑还根据其type值仅删除这些实体的子集?我应该将整个列表存储在Test对象中,然后继续进行过滤吗?

换句话说,我可以吗

db.delete(db.GqlQuery("SELECT * FROM TEST WHERE type = :1", "TEST")) 

或者更好地做像

这样的事情
#I don't know if something like this exists, it's just an example
testList = Test.all()
db.delete(testList.filter("type", "TEST"))

请注意,在第二个示例中,我首先实例化了某种Test对象,然后从该对象开始删除了实体。

我希望你明白我的意思,这件事在我的脑海里也很棘手,我不确定我是否解释得很好..

提前致谢,最好的问候

1 个答案:

答案 0 :(得分:2)

您的GQL没问题,但您应该只进行密钥查询,因为它更有效。

db.delete(db.GqlQuery("SELECT __key__ FROM TEST WHERE type = :1", "TEST"))

使用过滤器应该是

testList = Test.all(keys_only=True)
db.delete(testList.filter("type = ", "TEST"))

您会发现,对于生产中的大量记录,此方法无法扩展。尝试在具有数千个实体的Web请求中执行此操作很可能最终会导致DeadlineExceededError。

如果你在任务中运行删除,你将有10分钟的时间来完成你的请求,如果你真的很大,那么即使这样也行不通。

如果您只是想清除开发数据存储区,请使用命令行清除开发服务器启动时的数据存储区。

要考虑的其他一些事情。

如果您刚刚开始,请切换到ndb。您应该使用某种身份验证/访问控制来保护这种Web方法。考虑学习REST和方法。通常请求mutate不应该使用GET,但使用DELETE或POST。 - 只是要考虑的一些事情。