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 | +--------------+---------------+--------+
N+1 選択の問題を回避するために、これにReferenceProperty プリフェッチを使用する必要がありますか?
または
、以下のように注文書の品目でカテゴリ名とサブカテゴリ名を複製しますか?
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 の考え方を取り除くのは困難です。
では、このような典型的なシナリオの考え方を誰か教えてもらえませんか?
ありがとう!