我想了解如何将ReferenceProperty
用于常见的使用场景
在典型的应用程序中,我们始终显示Referenced Entity的列。
例如,考虑采购订单应用程序。
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()
这是我们通常在典型应用程序中显示的内容。
+---------------+---------------+--------+ | Category | Sub Category | Amount | +---------------+---------------+--------+ | Blue Category | Water | $12.00 | | Red Category | Fire | $20.00 | +---------------+---------------+--------+ | Purchase Order Total | $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)
我知道不是一个很好的可扩展解决方案,因为随着时间的推移,我们会有很多行项目需要更新。 RDBMS的思维方式难以摆脱。
那么有人可以教我如何思考这些典型场景吗?
谢谢!
答案 0 :(得分:1)
正如您所说,由于您经常可以编辑类别名称,因此不应将其嵌入到行项目中。
而是使用NDB(自动缓存获取)和多次获取(一次数据库调用以获取多个实体)来获取类别和子类别。