Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Python中删除GAE NBD实体并刷新Memchach后,它们仍然可以在数据存储查看器中看到_Python_Google App Engine_Google Cloud Datastore_App Engine Ndb - Fatal编程技术网

从Python中删除GAE NBD实体并刷新Memchach后,它们仍然可以在数据存储查看器中看到

从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_

下面是一个简单的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_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