我想了解如何ReferenceProperty
用于常见的使用场景。
在典型的应用程序中,我们总是显示引用实体的列。
例如,考虑一个采购订单应用程序。
class POCategory(db.Model):
name = db.StringProperty()
class POSubCategory(db.Model):
category = db.ReferenceProperty(POCategory, collection_name='sub_categories')
name = db.StringProperty()
class PurchaseOrder(db.Model):
total_amount = db.FloatProperty()
class PurchaseOrderLineItem(db.Model):
category = db.ReferenceProperty(POCategory, collection_name='po_line_items')
sub_category = db.ReferenceProperty(POSubCategory, collection_name = 'po_line_items')
amount = db.FloatProperty()
这是我们通常在典型应用程序中显示的内容。
+---------------+---------------+--------+ | 类别 | 子类别 | 金额 | +---------------+---------------+--------+ | 蓝色类别 | 水 | $12.00 | | 红色类别 | 火灾 | $20.00 | +---------------+---------------+--------+ | 采购订单总计 | $22.00 | +---------------+---------------+--------+
我应该为此使用ReferenceProperty Pre-fetching以避免 N+1 选择问题吗?
或
复制我的采购订单行项目中的类别和子类别名称,如下所示?
class PurchaseOrderLineItem(db.Model):
category = db.ReferenceProperty(POCategory, collection_name='po_line_items')
category_name = db.StringProperty()
sub_category = db.ReferenceProperty(POSubCategory, collection_name = 'po_line_items')
sub_category_name = db.StringProperty()
amount = db.FloatProperty()
显然,类别和子类别的名称是可编辑的。
因此,当有人更新name
属性时,我将不得不查询并遍历所有引用的PurchaseOrderLineItem
实体并更新我的重复name
属性。
#----------------------------------------
# BAD DESIGN
#----------------------------------------
po_category.name = 'New Category Name'
# build list of line items to be updated
update_list = []
for child_line_item in po_category.po_line_items:
child_line_item.category_name = po_entity.name
update_list.append(child_line_item)
db.put(po_category, update_list)
我知道这不是一个很好的可扩展解决方案,因为随着时间的推移,我们将有很多 Line Items 需要更新。RDBMS 的思维方式很难摆脱。
那么有人可以教我如何思考这些典型场景吗?
谢谢!