从Python中删除GAE NBD实体并刷新Memchach后,它们仍然可以在数据存储查看器中看到
下面是一个简单的Python示例,显示如何向NDB添加实体,然后将它们全部删除 然而,尽管实体似乎已被删除,但即使在我刷新从Python中删除GAE NBD实体并刷新Memchach后,它们仍然可以在数据存储查看器中看到,python,google-app-engine,google-cloud-datastore,app-engine-ndb,Python,Google App Engine,Google Cloud Datastore,App Engine Ndb,下面是一个简单的Python示例,显示如何向NDB添加实体,然后将它们全部删除 然而,尽管实体似乎已被删除,但即使在我刷新Memcache之后,datastoreviewer仍会显示它们。 我应该更改什么以便删除NDB实体? 我的代码: from google.appengine.ext import ndb from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_
Memcache之后,datastoreviewer
仍会显示它们。
我应该更改什么以便删除NDB实体?
我的代码:
from google.appengine.ext import ndb
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from models import Data
KEY = "fastsimon"
datum_key = dict()
class InvalidHandler(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Invalid entry')
class GetHandler(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Get!\n')
name = self.request.get('name')
out_str = "Should not be seen"
try:
ancestor_key = datum_key[name]
qry = Data.owner_query(ancestor_key)
data = qry.fetch()
out_str = data[-1].value
except KeyError:
out_str = "None"
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write(out_str)
class EndHandler(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('End!')
qry = Data.query().iter(keys_only=True)
print "before delete"
list_of_keys = list()
for q in qry:
print "ndb.Key('Datum',q):",ndb.Key('Datum',q.integer_id())
list_of_keys.append(ndb.Key('Datum',q.integer_id()))
print "list_of_keys:",list_of_keys
ndb.delete_multi(list_of_keys)
print "after delete"
for q in qry:
print "ndb.Key('Datum',q):",ndb.Key('Datum',q.integer_id())
class SetHandler(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Set!\n')
name=self.request.get('name')
data = Data(parent=ndb.Key("Datum", KEY),
name=name,
value=self.request.get('value'))
print "data:",data
ret_key = data.put()
datum_key[name] = ret_key
def main():
application = webapp.WSGIApplication([
('/get', GetHandler),
('/set', SetHandler),
('/end', EndHandler)],
debug=False)
global app
app = application
run_wsgi_app(app)
if __name__ == 'main':
main()
models.py:
from google.appengine.ext import ndb
class Data(ndb.Model):
name = ndb.StringProperty() # Upto 500 characters
value = ndb.TextProperty(required=True) # Unlimited length
@classmethod
def owner_query(cls, parent_key):
return cls.query(ancestor=parent_key).order(cls.name)
我采取的步骤:
data: Data(key=Key('Datum', 'fastsimon', 'Data', None), name=u'a', value=u'1')
INFO 2016-10-20 11:29:34,213 module.py:788] default: "GET /set?name=a&value=1 HTTP/1.1" 200 5
data: Data(key=Key('Datum', 'fastsimon', 'Data', None), name=u'b', value=u'2')
INFO 2016-10-20 11:29:50,442 module.py:788] default: "GET /set?name=b&value=2 HTTP/1.1" 200 5
before delete
ndb.Key('Datum',q): Key('Datum', 4661104668049408)
ndb.Key('Datum',q): Key('Datum', 5787004574892032)
list_of_keys: [Key('Datum', 4661104668049408), Key('Datum', 5787004574892032)]
after delete
INFO 2016-10-20 11:30:04,125 module.py:788] default: "GET /end HTTP/1.1" 200 4
但是,当我转到Data Store viewer并按下Flush Memcache时,仍然可以看到实体:
我应该更改什么以删除NDB实体?通常,在为实体使用祖先时,您需要小心查询-指定祖先键和不指定祖先键的查询将产生不同的(不重叠)结果。看 问题的根本原因是,如果各个实体都有祖先,则要删除的
密钥列表
中正在生成的密钥与原始密钥不匹配,因此传递给ndb的内容。delete\u multi
可能会丢失一些要删除的密钥
ndb.Key('Datum',q.integer_id())
为没有祖先的实体生成一个键,如果q
是具有祖先的实体的键,则该键将与q
键不匹配
一个简单的解决方案是不转换要删除的密钥,而是直接将它们传递到
ndb.delete_multi()
,例如,您可以简单地执行ndb.delete_multi([key for key in qry])
而不是ndb.delete_multi(密钥列表)
基于@DanCornilescu的优秀建议,我更改了EndHandler
的代码,它现在像champ一样删除实体
代码:
调试行:
data: Data(key=Key('Datum', 'fastsimon', 'Data', 4943129400573952), name=u'z', value=u'55')
INFO 2016-10-20 13:40:17,008 module.py:788] default: "GET /set?name=z&value=55 HTTP/1.1" 200 5
data: Data(key=Key('Datum', 'fastsimon', 'Data', 6069029307416576), name=u'x', value=u'88')
INFO 2016-10-20 13:40:28,556 module.py:788] default: "GET /set?name=x&value=88 HTTP/1.1" 200 5
datum_key.values(): [Key('Datum', 'fastsimon', 'Data', 4943129400573952), Key('Datum', 'fastsimon', 'Data', 6069029307416576)]
before delete
entity for Key('Datum', 'fastsimon', 'Data', 4943129400573952) => Data(key=Key('Datum', 'fastsimon', 'Data', 4943129400573952), name=u'z', value=u'55')
entity for Key('Datum', 'fastsimon', 'Data', 6069029307416576) => Data(key=Key('Datum', 'fastsimon', 'Data', 6069029307416576), name=u'x', value=u'88')
after delete
entity for Key('Datum', 'fastsimon', 'Data', 4943129400573952) => None
entity for Key('Datum', 'fastsimon', 'Data', 6069029307416576) => None
INFO 2016-10-20 13:40:40,517 module.py:788] default: "GET /end HTTP/1.1" 200 4
并且数据存储查看器不显示任何实体。您还应该打印查询中使用的祖先密钥,并检查数据存储中的实体是否与该祖先匹配。
所有者查询和EndHandler
查询不匹配:一个是祖先查询,另一个不是,EndHandler的目的是删除属于我的所有实体,那么-我还需要检查祖先@DanCornilescu吗?另外,删除后的行后面没有打印任何内容,这难道不表明实体被假定删除了吗?并且在EndHandler
中构建的键列表可能包含不存在的键:当执行ndb.Key('Datum',q.integer_id())
时,您将创建一个没有祖先的键,如果原始的q
键有一个祖先,那么它将不匹配ndb.delete_multi()
不会抱怨密钥不存在。你为什么不直接调用ndb.delete_multi(qry)
-因为qry
已经包含了你想要删除的实际密钥?我认为我不能传递qry
,因为它属于QueryIterator类型。
data: Data(key=Key('Datum', 'fastsimon', 'Data', 4943129400573952), name=u'z', value=u'55')
INFO 2016-10-20 13:40:17,008 module.py:788] default: "GET /set?name=z&value=55 HTTP/1.1" 200 5
data: Data(key=Key('Datum', 'fastsimon', 'Data', 6069029307416576), name=u'x', value=u'88')
INFO 2016-10-20 13:40:28,556 module.py:788] default: "GET /set?name=x&value=88 HTTP/1.1" 200 5
datum_key.values(): [Key('Datum', 'fastsimon', 'Data', 4943129400573952), Key('Datum', 'fastsimon', 'Data', 6069029307416576)]
before delete
entity for Key('Datum', 'fastsimon', 'Data', 4943129400573952) => Data(key=Key('Datum', 'fastsimon', 'Data', 4943129400573952), name=u'z', value=u'55')
entity for Key('Datum', 'fastsimon', 'Data', 6069029307416576) => Data(key=Key('Datum', 'fastsimon', 'Data', 6069029307416576), name=u'x', value=u'88')
after delete
entity for Key('Datum', 'fastsimon', 'Data', 4943129400573952) => None
entity for Key('Datum', 'fastsimon', 'Data', 6069029307416576) => None
INFO 2016-10-20 13:40:40,517 module.py:788] default: "GET /end HTTP/1.1" 200 4