我正在尝试从数据存储表中删除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对象,然后从该对象开始删除了实体。
我希望你明白我的意思,这件事在我的脑海里也很棘手,我不确定我是否解释得很好..
提前致谢,最好的问候
答案 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。 - 只是要考虑的一些事情。