简而言之,我必须在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)
这会按预期工作吗?谢谢你的帮助!
答案 0 :(得分:0)
您的策略将起作用,这是使用这些游标的重点,因为它们是高效的,您可以按照预期获得下一批,而不管前一个游标发生了什么。
在旁注中,您还可以优化UpdateCustomer
,而不是逐个检索/保存,您可以使用batches在ndb.put_multi_async
中执行操作。