使用游标进行分页时更新ndb中的实体

时间:2015-01-03 09:54:34

标签: entity-framework google-app-engine secondlife

简而言之,我必须在Second Life中创建一个脚本,与更新ndb数据库中的记录的AppEngine应用程序进行通信。从数据库中提取的记录将作为批处理(页面)发送到更新客户的LSL脚本,然后要求Web应用程序将这些客户标记为在数据库中更新。

要创建批处理,我在(整数)属性update_ver==0上使用查询,并使用fetch_page()生成到下一批的游标。此游标也以urlsafe() - 编码参数的形式发送到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)

更新数据库中的Customer实体的处理程序如下。 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)

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

1 个答案:

答案 0 :(得分:0)

您的策略将起作用,这是使用这些游标的重点,因为它们是高效的,您可以按照预期获得下一批,而不管前一个游标发生了什么。

在旁注中,您还可以优化UpdateCustomer,而不是逐个检索/保存,您可以使用batchesndb.put_multi_async中执行操作。