2011-11-18 73 views
0

比方說,我在建模一個網站,網頁會被PageModel表示,像這樣:延遲加載谷歌應用程序引擎大/複雜的模特屬性

class PageModel(db.Model): 
    name = db.StringProperty() 
    parentPage = db.SelfReferenceProperty() 
    content = db.TextProperty() 

我想成爲能夠拉出所有頁面對象的列表,以便呈現菜單等,但不必爲所有項目拉入內容。你會如何模擬這個對象,以便只有在需要時才能提取內容?它是否需要與單獨的「內容」模型建立一對一的引用關係?如果是這樣,你會參考page對象還是content對象?

回答

2

您可以將content屬性移動到新模型(PageContentModel)中。我將通過使PageContentModel的父項成爲PageModel(使用db.Model的父屬性)來實現引用。這允許您在單個事務中修改它們(因爲它們在單個實體組中)。與具有對PageModel的引用PageContentModel(而不是在PageModel具有與PageContentModel參考)建模事情

一個好處是,如果你需要的內容大於1MB您可以通過允許每個這麼做PageModel擁有一個或多個PageContentModel對象,您只需將您的內容分割爲1MB塊並將每個塊寫入不同的PageContentModel實例。爲了能夠獲取內容,您需要PageContentModel對象具有與它們關聯的「訂單」屬性,以便您可以按正確的順序重新構建內容。

要查詢相關的PageModel你可以使用祖先過濾器這樣的PageContentModel實例:

PageContentModel.all().ancestor(page_model_instance) 

至於建議的@Nick另一種方式來做到這一點是使用了files api寫的內容到blobstore中的blob,然後通過在PageModel上創建BlobReferenceProperty將該Blob鏈接到PageModel。我現在有機會嘗試這個,它工作得很好(儘管它是一個實驗性功能)。這將允許您的內容非常大,並且在新的定價模式下,實際上比將內容存儲在數據存儲模型中更便宜。

更新於2012年2月7日包括@Nick關於blobstore的建議。

+0

好主意Bryce-謝謝 – Yarin

+0

沒問題。我在我的一個應用程序中完成了這項工作,其中有數千篇文章,每篇文章可能有數兆字節的內容。當內容曾經是父模型的一部分時,每次我查詢其中的大量時,結果對象會將處理程序推到軟內存限制上。將內容移入子模型允許我保持內存使用的正常,並允許我爲每篇文章存儲更大的內容。由於我只在顯示單個文章的頁面上使用內容,因此額外的查詢使該頁面不會太糟糕。 –

+0

真棒 - 感謝您的更新 - 去爲它 – Yarin