Сопоставить сырой SQL с несколькими связанными моделями Django - PullRequest
2 голосов
/ 17 апреля 2009

По соображениям производительности я не могу использовать методы запросов ORM в Django, и мне приходится использовать сырой SQL для некоторых сложных вопросов. Я хочу найти способ отобразить результаты запроса SQL на несколько моделей.

Я знаю, что могу использовать следующий оператор для сопоставления результатов запроса с одной моделью, но я не могу понять, как использовать его для сопоставления с соответствующими моделями (как я могу сделать с помощью оператора select_related в Django ).

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

Существует ли относительно простой способ сопоставления полей связанных таблиц, которые также находятся в наборе результатов запроса?

1 Ответ

1 голос
/ 17 апреля 2009

Во-первых, можете ли вы доказать, что ORM останавливает вашу работу? Иногда проблемы с производительностью просто плохой дизайн базы данных или неправильные индексы. Обычно это происходит из-за попытки принудительно вписать ORM Django в устаревший дизайн базы данных. Хранимые процедуры и триггеры могут оказывать негативное влияние на производительность - особенно при работе с Django, где код триггера должен находиться в коде модели Python.

Иногда плохая производительность является проблемой приложения. Это включает в себя ненужные операции упорядочения, выполняемые в базе данных.

Самая распространенная проблема с производительностью - это приложение, которое «перегружает» данные. Случайно используя метод .all() и создавая большие коллекции в памяти. Это сокрушит производительность. К наборам запросов Django нужно прикасаться как можно меньше, чтобы итератор набора запросов передавался шаблону для отображения.

Как только вы решите обойти ORM, вам придется бороться с проблемой несоответствия объектно-реляционного импеданса. Снова. В частности, реляционная «навигация» не имеет понятия «связанный»: это должна быть первоклассная выборка реляционного набора с использованием внешних ключей. Собрать сложную объектную модель в памяти через SQL просто сложно. Циркулярные ссылки делают это очень трудно; трудно разбить ФК на коллекции.

Если вы собираетесь использовать сырой SQL, у вас есть два варианта.

  1. Откажитесь от "select related" - его не существует - и это болезненно для реализации.

  2. Изобретите свои собственные ORM-подобные «выберите связанные» функции. Обычный подход заключается в добавлении получателей с сохранением состояния, которые (а) проверяют частный кеш, чтобы увидеть, извлекли ли они связанный объект и, если объект не существует, (б) извлечь связанный объект из базы данных и обновить кэш.

В процессе изобретения собственных получателей с сохранением состояния вы будете заново изобретать Django и, вероятно, обнаружите, что это не слой ORM, а проект базы данных или проблема разработки приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...