gpt4 book ai didi

python - StructuredProperty 是否引用父级或子级?

转载 作者:行者123 更新时间:2023-11-30 23:24:48 27 4
gpt4 key购买 nike

StructuredProperty 是否引用父级或子级?

class Invoices(ndb.Model): #Child

class Customers(ndb.Model): #Parent
invoice = ndb.StructuredProperty(Invoices)

或者...

class Customers(ndb.Model): #Parent

class Invoices(ndb.Model): #Child
customer = ndb.StructuredProperty(Customers)

最佳答案

为了回答“NoSQL 数据存储的更好实践是什么”的问题,这是我可以提供的。

首先,您可能想以单数命名您的模型,因为它们应该描述一个InvoiceCustomer 实体,而不是多个。

接下来,使用 StructuredProperty 意味着您希望将所有这些信息保存在单一实体 - 这将减少写/读操作,但可能会引入一些限制。(参见 docs -或者这个related question )

最常见的关系是一对多(发票)关系,您可以按如下方式构建:

class Invoice(ndb.Model): #Child
invoice_id = ndb.StringProperty(required=True) #

class Customer(ndb.Model): #Parent
invoices = ndb.StructuredProperty(Invoices, repeated=True)

def get_invoice_by_id(self, invoice_id):
"""Returns a customer Invoice by invoice_id. Raises KeyError if invoice is not present."""
invoice_matches = [iv for iv in self.invoices if iv.invoice_id == invoice_id]
if not invoice_matches: raise KeyError("Customer has no Invoice with ID %s" % invoice_id)
return invoice_matches[0] # this could be changed to return all matches

请记住此实现的以下限制:

  1. StructuredProperty内部不能包含重复的属性。
  2. 保持 invoice_id 全局唯一的复杂性将比 Invoice 位于其自己的实体组中更高。 (invoice_key.get() 总是比所需的查询更好))
  3. 您需要在 Customer 上使用一个实例方法来通过 invoice_id 查找Invoice
  4. 您需要逻辑来防止单个客户上存在具有相同 ID 的发票

以下是一些优点:

  1. 您可以查询客户
  2. 通过 invoice_id 查询 Invoice 将返回 Customer 实例以及所有发票。 (实际上,这可能是一个优点,也可能是一个缺点 - 您需要逻辑来从客户处返回发票)

这是一个更常见的解决方案,但它绝不一定是“正确的解决方案”。此解决方案使用祖先关系,允许您继续写入 Invoice 和相关的 Customer 原子 - 这样您就可以维护有关的汇总发票统计信息客户级别。 (total_orderstotal_gross 等)

class Invoice(ndb.Model):
customer = ndb.ComputedProperty(lambda self: self.key.parent(), indexed=False) # when not indexed, this is essentially a @property

class Customer(ndb.Model):
def get_invoice_by_id(self, invoice_id):
"""Returns a customer Invoice by invoice_id. Raises KeyError if invoice is not present."""
invoice_key = ndb.Key(Invoice._get_kind(), invoice_id, parent=self.key)
return invoice_key.get()

def query_invoices(self):
"""Returns ndb.Query for invoices by this Customer."""
return self.query(ancestor=self.key)

invoice = Invoice(parent=customer.key, **invoice_properties)

祝 Appengine 好运!一旦掌握了这一切的窍门,这就是一个真正有益的平台。

更新:

正如我上面提到的,这是一些用于以事务方式更新客户汇总总数的附加代码。

def create_invoice(customer_key, gross_amount_paid):
"""Creates an invoice for a given customer.

Args:
customer_key: (ndb.Key) Customer key
gross_amount_paid: (int) Gross amount paid by customer
"""

@ndb.transactional
def _txn():
customer = customer_key.get()
invoice = Invoice(parent=customer.key, gross_amount=gross_amount_paid)

# Keep an atomic, transactional count of customer aggregates
customer.total_gross += gross_amount_paid
customer.total_orders += 1

# batched put for API optimization
ndb.put_multi([customer, invoice])

return invoice

return _txn()

上述代码适用于单个实体组事务(例如ndb.transactional(xg=False)),因为Invoice是一个子实体实体到客户。如果该连接丢失,您将需要 xg=True。 (我不确定它是否更贵,但优化程度较低)

关于python - StructuredProperty 是否引用父级或子级?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23274842/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com