2013-04-26 63 views
0

我想了解如何在常見使用場景下使用ReferenceProperty
在典型的應用程序中,我們始終顯示引用實體的列。我應該使用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() 

這是我們通常在典型應用中顯示的內容。

+---------------+---------------+--------+ 
| Category | Sub Category | Amount | 
+---------------+---------------+--------+ 
| Blue Category | Water   | $12.00 | 
| Red Category | Fire   | $20.00 | 
+---------------+---------------+--------+ 
|   Purchase Order Total | $22.00 | 
+---------------+---------------+--------+

我應該使用的ReferenceProperty預取此避免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的思維方式很難擺脫。

那麼任何人都可以請教我如何思考這些典型的場景?

謝謝!

回答

1

正如您所說,由於您可以經常編輯類別名稱,因此不應將其嵌入到「行項目」中。

取而代之的是使用NDB(自動緩存獲取)和多重獲取(一個數據庫調用來獲取多個實體)來獲取類別和子類別。

+0

是的NDB比DB有更好的API設計,我只需要做ReferenceProperty預取技術來執行「SQL-JOIN-like」操作。不要繞過它。謝謝您的回答。 – stun 2013-04-28 16:40:57

相關問題