ndb.transactional如何分组实体?

时间:2013-11-15 07:29:38

标签: python google-app-engine transactions google-cloud-datastore app-engine-ndb

此应用程序适用于租赁服务。当工具分发时,我需要在工具''who_has'属性上保存客户密钥,并在分发处理订单中添加工具密钥。如果出现任何问题,我需要删除之前写的所有'who_has'属性。

我认为Trancastions是这样做的方式。所以这是我的代码

def get_tools(tool_ids):
    tools =[]
    for t in tool_ids:
            tool = classes.ToolUnits.get_by_id(int(t))
            tools.append(tool)

    return tools

@ndb.transactional(xg=True)
def process_handout(self):
    customer_id = self.request.get("customer")
    tool_ids = self.request.get("units")

    if not customer_id == 'false' and (not tool_ids=="[]" or not tool_ids):
        customer = classes.Customers.get_by_id(int(customer_id))

        order = classes.Orders(
            customer = customer.key,
            handout = True,
            transferred = [],
            booked = [],
        )

        tools = get_tools(json.loads(tool_ids))

        for tool in tools:

            if not tool.who_has:
                tool.who_has = customer.key
                order.transferred.append(tool.key)
                tool.put()
            else:
                # if tool is already taken
                order.booked.append(tool.key)

        order.put()
        self.redirect('/order/%s' % order.key.id())
    else:
        self.redirect('/tools')

工作正常两个工具,但8个工具抛出错误: BadRequestError: operating on too many entity groups in a single transaction.

显然每个tool.put()都被视为实体组。我如何在一个团体下团结他们?

我尝试了文档,但这对我来说都是中文。你能解释一下我的例子,PLZ?

1 个答案:

答案 0 :(得分:3)

您正在使用limited to 5 entities participating in the transaction的跨群组(xg=True)交易。

实体组由ancestor path定义:这仅表示对于特定实体(或多个实体)定义父实体,对于该父实体,您可以再次定义父实体,基本上定义一个树实体。所有这些实体都属于同一个实体组。组的根是树根的实体:其他实体定义为父(直接或间接)的实体,但它本身没有父类定义。

如果您没有定义实体的父级,并且您也不使用此实体作为其他实体的父级,则此实体是其自己的实体组的根。

简化原理:实体组基本上是指“将所有实体放在同一台机器上”,以便GAE可以轻松地对它们进行交易更改。

限制是实体组(=实体组内的所有实体)每秒只能更新一次。因此,您需要小心如何构建数据。一种好的方法是将用户用作实体组的根,因为用户独立行为并且往往不会在很短的时间内创建多个请求。

希望这样清楚一些事情。