2009-04-17 5 views
2

パフォーマンス上の理由から、私はDjangoのORMクエリメソッドを使用することができず、いくつかの複雑な質問に対しては未処理のSQLを使用する必要があります。私はSQLクエリの結果をいくつかのモデルにマップする方法を探したい。生のSQLを複数の関連するDjangoモデルにマップする

次の文を使用してクエリ結果を1つのモデルにマップできますが、関連するモデルにマップできるようにする方法を理解できません(select_related文を使用して実行できます)。 Django)。

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

クエリ結果セットにも含まれる関連テーブルのフィールドをマップすることは比較的簡単な方法はありますか?

答えて

1

まず、ORMがパフォーマンスを停止していることを証明できますか?パフォーマンスの問題は、単にデータベース設計が不適切であるか、インデックスが不適切な場合があります。通常これは、DjangoのORMを従来のデータベース設計に強制的に適合させることから来ています。ストアドプロシージャとトリガは、特にトリガコードがPythonモデルコードに含まれると予想されるDjangoで作業する場合、パフォーマンスに悪影響を与える可能性があります。

パフォーマンスが低下するとアプリケーションの問題が発生することがあります。これには、データベース内で不必要な受注操作が行われることも含まれます。

最も一般的なパフォーマンスの問題は、データを「オーバーフェッチ」するアプリケーションです。簡単に.all()メソッドを使用し、大きなメモリ内コレクションを作成する。これによりパフォーマンスが低下します。 Djangoのクエリセットは、クエリーセットのイテレータが表示のためにテンプレートに渡されるように、できるだけ触れなければなりません。

ORMをバイパスすることを選択したら、オブジェクト・リレーショナル・インピーダンスの不一致の問題を解決する必要があります。再び。具体的には、リレーショナルの「ナビゲーション」には「関連」という概念がありません。外部キーを使用するリレーショナルセットのファーストクラスのフェッチでなければなりません。 SQLを介して複雑なメモリ内オブジェクトモデルをアセンブルするのは簡単ではありません。循環参照はこれを非常に難しくします。 FKのコレクションへの解決は難しいです。

生のSQLを使用する場合は、2つの選択肢があります。

  1. Eschew "選択関連" - それは存在しません - 実装するのは苦労します。

  2. ORMのような「関連する選択」機能を独自に作成します。一般的なアプローチは、(a)プライベートキャッシュをチェックして関連オブジェクトをフェッチしたかどうか、およびオブジェクトが存在しないかどうかを確認する(b)データベースから関連オブジェクトをフェッチしてキャッシュを更新するステートフルゲッターを追加することです。あなた自身のステートフルなゲッターを発明する過程で

、あなたはDjangoのを再発明することがあります、そしてあなたはそれがORM層が、データベース設計やアプリケーションの設計上の問題ではないことをおそらく発見するでしょう。

+0

パフォーマンスの問題は、ORM自体のいくつかの制限を回避しなければならないためです。データベース設計は良いです(従来のデータベースはありません)。多分私はDjangoでクエリを書くためのより簡単な方法があるかどうか尋ねるべきです。 SQLでは、クエリは本当に簡単です。しかし、それは独自の話題になるでしょう。 ;-) – Michael

+1

これは私の指摘です - Django ORMで実際に動作するDjango ORMクエリを取得し、すべてが改善されます。 「制限」が何であれ、それは簡単な誤解や修正が可能なアプリケーション設計上の問題かもしれません。 –

+1

回答では質問が解決されず、その問題が別の場所にある可能性が示唆されます。投票した。 プラットフォームの欠点のために、特定のDBプラットフォームでスケーリングすると、うまく設計されたDBスキーマでもパフォーマンスの問題が発生する可能性があります。これらの欠点は、未処理のクエリの最適化を完全に克服することができ、アプリケーションやスキーマ設計の問題は根本的なものではないことを暗示します。ときどき問題は/データベースであり、それが尋ねられた質問です。 – stealthwang

関連する問題