2009-04-17 92 views
2

由於性能方面的原因,我無法使用Django的ORM查詢方法,因此我必須對一些複雜問題使用原始SQL。我想找到一種將SQL查詢的結果映射到多個模型的方法。將原始SQL映射到多個相關的Django模型

我知道我可以使用以下語句將查詢結果映射到一個模型,但我無法計算如何使用它來映射到相關模型(就像我可以通過在select_related語句中使用Django的)。

model_instance = MyModel(**dict(zip(field_names, row_data))) 

是否有一種相對簡單的方法可以映射也在查詢結果集中的相關表的字段?

回答

1

首先,你能證明ORM阻止你的表現嗎?有時性能問題只是數據庫設計不佳或索引不當。通常這是因爲試圖將Django的ORM強制適用於傳統數據庫設計。存儲過程和觸發器可能會對性能產生負面影響 - 特別是在使用Django時,預計觸發器代碼將位於Python模型代碼中。

有時性能差是應用程序問題。這包括在數據庫中進行的不必要的操作。

最常見的性能問題是「超量」數據的應用程序。隨便使用.all()方法並創建大型內存集合。這會壓制表演。必須儘可能少地觸及Django查詢集,以便將查詢集迭代器提供給模板以供顯示。

一旦您選擇繞過ORM,您必須解決對象關係阻抗不匹配問題。再次。具體而言,關係「導航」沒有「相關」的概念:它必須是使用外鍵的關係集的一級抓取。通過SQL組裝一個複雜的內存中對象模型非常困難。循環引用使這非常困難;將FK解析爲集合很難。

如果您打算使用原始SQL,您有兩種選擇。

  1. 迴避「選擇相關」 - 它不存在 - 實施起來很痛苦。

  2. 創建您自己的類ORM「選擇相關」功能。一種常見的方法是添加有狀態的getter(a)檢查私有緩存以查看他們是否已經獲取相關對象,如果對象不存在,(b)從數據庫中獲取相關對象並更新緩存。

在發明了自己的有狀態干將,你會被重塑Django的過程中,你可能會發現,它不是ORM層,但一個數據庫設計或應用程序設計問題。

+0

性能問題是由於我不得不繞過ORM本身的一些限制。數據庫設計很好(沒有遺留數據庫)。也許我應該問是否有更簡單的方法來用Django編寫查詢。在SQL中,查詢非常簡單。但這將是一個自己的話題。 ;-) – Michael 2009-04-17 12:00:35