1

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

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

表测试

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

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

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的实体,我已经使用了all()Test类的方法,我是否也必须使用相同的逻辑来只删除一个子集那些实体,基于它们的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 对象,然后删除了从该对象开始的实体。

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

在此先感谢,最好的问候

4

1 回答 1

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 和方法论。通常不应该使用 GET 来完成变异请求,而是使用 DELETE 或 POST。- 只是一些需要考虑的事情。

于 2013-07-24T10:49:18.593 回答