【问题标题】:Updating entities in ndb while paging with cursors使用游标分页时更新 ndb 中的实体
【发布时间】:2015-03-01 11:02:53
【问题描述】:

为了简单起见,我必须在 Second Life 中编写一个脚本,与更新 ndb 数据库中记录的 AppEngine 应用程序进行通信。从数据库中提取的记录作为批次(一个页面)发送到 LSL 脚本,该脚本会更新客户,然后要求 Web 应用程序将这些客户标记为在数据库中已更新。

为了创建批次,我对(整数)属性update_ver==0 使用查询,并使用fetch_page() 生成指向下一个批次的游标。此光标也作为urlsafe()-encoded 参数发送到 LSL 脚本。

为了将客户标记为已更新,update_ver 设置为其他值,例如 2,并且实体通过 put_async() 更新。然后 LSL 脚本通过之前发送的光标获取下一批。

我比较简单的问题是:在网络应用程序中,由于查询属性update_ver 不再满足过滤器,我的光标是否仍然有效?还是我必须使用其他策略?

去掉不相关的部分(包括身份验证),我的代码目前看起来像这样(客户是我数据库中的实体)。

class GetCustomers(webapp2.RequestHandler):    # handler that sends batches to the update script in SL
    def get(self):
        cursor=self.request.get("next",default_value=None)
        query=Customer.query(Customer.update_ver==0,ancestor=customerset_key(),projection=[Customer.customer_name,Customer.customer_key]).order(Customer._key)
        if cursor:
            results,cursor,more=query.fetch_page(batchsize,start_cursor=ndb.Cursor(urlsafe=cursor))
        else:
            results,cursor,more=query.fetch_page(batchsize)
        if more:
            self.response.write("more=1\n")
            self.response.write("next={}\n".format(cursor.urlsafe()))
        else:
            self.response.write("more=0\n")
        self.response.write("n={}\n".format(len(results)))
        for c in results:
            self.response.write("c={},{},{}\n".format(c.customer_key,c.customer_name,c.key.urlsafe()))
        self.response.set_status(200)

更新数据库中客户实体的处理程序如下。 c= 参数是要更新的记录的urlsafe() 编码实体键,nv= 参数是其update_ver 属性的新版本号。

class UpdateCustomer(webapp2.RequestHandler):
    @ndb.toplevel   # don't exit until all async operations are finished
    def post(self):
        updatever=self.request.get("nv")
        customers=self.request.get_all("c")
        for ckey in customers:
            cust=ndb.Key(urlsafe=ckey).get()
            cust.update_ver=nv   # filter in the query used to produce the cursor was using this property!
            cust.update_date=datetime.datetime.utcnow()
            cust.put_async()
    else:
        self.response.set_status(403)

这会按预期工作吗?感谢您的帮助!

【问题讨论】:

    标签: entity-framework google-app-engine linden-scripting-language


    【解决方案1】:

    您的策略会奏效,这就是使用这些游标的全部意义所在,因为它们很有效,而且无论前一批发生了什么,您都可以按预期获得下一批。

    顺便说一句,您还可以优化您的UpdateCustomer,而不是一个一个地检索/保存,您可以在batches 中执行操作,例如使用ndb.put_multi_async

    【讨论】:

    • 感谢您的回答和提示。
    猜你喜欢
    • 2015-03-26
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 2017-07-11
    • 1970-01-01
    相关资源
    最近更新 更多