django - руководство по ORM для пользователей SQL? - PullRequest
9 голосов
/ 04 февраля 2010

В django встроен этот сложный ORM, но, потратив много времени на него, мне все еще сложно делать запросы, которые на удивление просты в SQL. Есть даже некоторые простые вещи, которые я не могу найти способ сделать через ORM django (например, «выбрать отличный столбец1 из имени таблицы»).

Существует ли какая-либо документация, в которой показано "Для общих операторов SQL, вот как вы это делаете в django"?

(я сначала попробовал Google, но либо его там нет, либо я просто не могу придумать правильный запрос ...)

Ответы [ 4 ]

8 голосов
/ 04 февраля 2010

Есть некоторые вещи, которые смехотворно просты в SQL, которые трудно или невозможно с помощью ORM. Это называется « несоответствием объектно-реляционного импеданса ». По сути, ORM обрабатывает каждую строку в базе данных как отдельный объект. Поэтому операции, связанные с обработкой значений отдельно от их ряда, становятся довольно сложными. Последние версии Django (1.1+) несколько улучшают эту ситуацию благодаря поддержке агрегации , но во многих случаях будет работать только SQL.

Для этого django предоставляет несколько способов, позволяющих вам просто перейти в raw sql. Некоторые из них возвращают объекты модели как результаты, в то время как другие приводят вас к соединителю DBAPI2. Самый низкий уровень выглядит так:

from django.db import connection

cursor = connection.cursor()
cursor.execute("SELECT DISTINCT column1 FROM tablename")
row = cursor.fetchone()

Если вы хотите вернуть набор запросов из SQL-запроса, используйте raw () в менеджере вашей модели:

qs = ModelName.objects.raw("""SELECT first_name 
                              FROM myapp_modelname 
                              WHERE last_name = 'van Rossum'")
for person in qs:
     print person.first_name # Result already available
     print person.last_name  # Has to hit the DB again

Примечание: raw () доступно только в разрабатываемой версии Django, которая должна быть объединена в транк с 1.2.

Полная информация доступна в документации по Выполнение необработанных запросов SQL .

6 голосов
/ 04 февраля 2010

Думайте об этом так.

"Для обычных хакерских атак SQL, что в первую очередь предполагалось делать объектно-ориентированным?"

Проблема не в том, что ORM сложный. Дело в том, что ваш мозг был искривлен в форме SQL, что затрудняет четкое видение объектов.

Общие правила:

  • Если вы думаете, что это просто ВЫБРАТЬ ОТ ГДЕ, остановитесь. Спросите, какие объекты вам нужно было видеть в наборе результатов. Затем найдите эти объекты и поработайте с менеджером объектов.

  • Если вы думаете, что это просто СОЕДИНЕНИЕ, остановитесь. Спросите, какой основной объект вы хотите. Помните, что объекты не используют внешние ключи. Присоединиться ничего не значит. Кажется, что объект нарушает 1NF и содержит в себе и весь набор связанных объектов. Затем найдите «первичные» объекты и поработайте с менеджером объектов. Используйте запросы связанных объектов для поиска связанных объектов.

  • Если вы думаете, что это НАРУЖНОЕ СОЕДИНЕНИЕ, остановитесь. Спросите, какие две вещи вы хотите видеть в наборе результатов. Внешнее соединение - это то, что присоединится к UNIONED с вещами, которые не присоединятся. Какие вещи в первую очередь. Затем найдите «первичные» объекты и поработайте с менеджером объектов. Некоторые будут иметь наборы связанных объектов. Некоторые не будут.

  • Если вы думаете, что это ГДЕ СУЩЕСТВУЕТ или ГДЕ ВХОДИТ с подзапросом, ваша модель, вероятно, неполная. Иногда требуется необычное соединение. Но если вы делаете такую ​​проверку, это обычно означает, что вам нужно свойство в вашей модели.

  • Если вы считаете, что вам нужно выбрать SELECT DISTINCT, вы полностью пропустили лодку. Это просто набор Python. Вы просто получаете значения столбцов в набор Python. Это различные значения.

  • Если вы считаете, что вам нужна GROUP BY, вы игнорируете Python collections.defaultdict. Использование Python для GROUP BY обычно быстрее, чем возиться с SQL.

    За исключением хранилищ данных. Что вы не должны делать в Джанго. Вы должны использовать SQLAlchemy для хранилища данных.

4 голосов
/ 04 февраля 2010

Хорошей отправной точкой для выполнения запросов Django являются сами документы Django.

http://docs.djangoproject.com/en/dev/topics/db/queries/

Вот несколько примеров:

select * from table
=
ModelName.objects.all()

фильтрация:

select * from table where column = 'foo'
=
ModelName.objects.filter(column='foo')

В частности, в отношении использованияячейки вы используете метод diver () набора запросов Django.

Вот соответствующая ссылка в документации.http://docs.djangoproject.com/en/dev/ref/models/querysets/#distinct

Обновление: ORM помогает вам, позволяя вам использовать объектно-ориентированное взаимодействие с вашими данными.Вы не пишете код, который переводит набор результатов вашего запроса в набор объектов.Это делает это автоматически.Это фундаментальное изменение в мыслительном процессе, которое вы должны сделать.

Вы начинаете думать в терминах: «У меня есть этот объект, мне нужно получить все другие объекты, которые похожи на него». Затем вы можете задать ORM.для этих объектов.ORM, мне нужны все объекты класса Product, которые имеют атрибут цвета "синий"

Специальный язык ORM Джанго для этого:

products = Product.objects.filter(color='blue')

Это делается вместо:

  • написание SQL-запроса,
  • , правильное экранирование всех аргументов,
  • подключение к базе данных,
  • , запрос к базе данных и обработка соединения / запросаошибки,
  • получение набора результатов,
  • итерации по набору результатов, преобразование возвращаемых значений в надлежащие объекты, для которых можно вызывать методы.

Это значениев использовании ORM.Упрощение кода и сокращение времени разработки.

2 голосов
/ 05 февраля 2010

Для конкретных инструкций вы должны сделать это так:

MyModel.objects.values_list('column1', flat=True).distinct()

Но другие авторы правы, говоря, что вы не должны думать, «как мне написать этот SQL в ORM». Когда вы изучали Python, исходящий из Java, C ++ или чего-то еще, вы вскоре научились выходить из мышления «как писать этот код Java на Python» и просто сосредоточились на решении проблемы с помощью Python. То же самое относится и к использованию ORM.

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