django имеет этот сложный ORM, встроенный к нему, но после проведения большого количества времени на нем, мне все еще трудно сделать запросы, которые удивительно просты в SQL. Существуют даже некоторые простые вещи, которые я не могу найти способ сделать через django ORM (например, 'выбирают отличный column1 из имени таблицы').
Есть ли какая-либо документация, которая показывает "Для общих SQL-операторов, вот то, как Вы делаете это в django"?
(Я действительно пробовал Google сначала, но или это не там, или я просто не могу думать о правильном запросе...),
Есть некоторые вещи, которые до смешного просты в SQL, но которые трудно или невозможно реализовать с помощью ORM. Это называется « объектно-реляционным несоответствием импеданса ». По сути, ORM обрабатывает каждую строку в базе данных как отдельный объект. Поэтому операции, связанные с обработкой значений отдельно от их строки, становятся довольно сложными. Последние версии Django (1.1+) несколько улучшают эту ситуацию за счет поддержки агрегации , но для многих вещей будет работать только SQL.
С этой целью django предоставляет несколько методов, позволяющих очень просто перейти к необработанному 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-запросов .
Хорошей отправной точкой для выполнения запросов 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')
В частности, что касается использования отдельных, вы используете отдельные () метод набора запросов Django.
Вот соответствующая ссылка в документации. http://docs.djangoproject.com/en/dev/ref/models/querysets/#distinct
Обновление: {{1} } ORM помогает вам, позволяя использовать объектно-ориентированное взаимодействие с вашими данными. Вы не пишете код, который переводит набор результатов вашего запроса в набор объектов. Делает это автоматически. Это фундаментальное изменение в мыслительном процессе, которое вам необходимо произвести.
Вы начинаете думать в терминах «У меня есть этот объект, мне нужно получить все другие подобные ему объекты». Затем вы можете запросить ORM для этих объектов. ORM, мне нужны все объекты Class Product, у которых есть атрибут цвета "синий"
. Для этого используется специальный язык ORM Django:
products = Product.objects.filter(color='blue')
Это делается вместо:
Это ценность использования ORM. Упрощение кода и сокращение времени разработки.
Подумайте об этом способ.
«Что я должен был делать в первую очередь для обычных обходов SQL?»
Проблема не в том, что ORM сложен. Дело в том, что ваш мозг был искажен в форме SQL, из-за чего трудно четко видеть объекты.
Общие правила:
Если вы думаете, что это простой SELECT FROM WHERE, остановитесь. Спросите, какие объекты вам нужно было увидеть в наборе результатов. Затем найдите эти объекты и работайте с диспетчером объектов.
Если вы думаете, что это простой JOIN, остановитесь. Спросите, какой основной объект вам нужен. Помните, что объекты не используют внешние ключи. Присоединиться ничего не значит. Кажется, что объект нарушает 1NF и содержит в себе весь набор связанных объектов. Затем найдите «первичные» объекты и работайте с диспетчером объектов. Используйте запросы связанных объектов, чтобы найти связанные объекты.
Если вы думаете, что это ВНЕШНЕЕ СОЕДИНЕНИЕ, остановитесь. Спросите, какие две вещи вы хотите увидеть в наборе результатов. Внешнее соединение - это вещи, которые присоединяются к UNIONED с вещами, которые не присоединяются. Какие вещи в первую очередь. Затем найдите «первичные» объекты и работайте с диспетчером объектов. У некоторых будут наборы связанных объектов. Некоторые не будут.
Если вы думаете, что это WHERE EXISTS или WHERE IN с подзапросом, ваша модель, вероятно, неполная. Иногда требуется необычное соединение. Но если вы проводите такую проверку, это обычно означает, что вам нужно свойство в вашей модели.
Если вы думаете, что вам нужен SELECT DISTINCT, вы полностью пропустили лодку. Это просто набор Python. Вы просто получаете значения столбцов в набор Python. Это разные ценности.
Если вы считаете, что вам нужна GROUP BY, вы игнорируете Python collections.defaultdict
. Использование Python для GROUP BY обычно быстрее, чем возня с SQL.
За исключением хранилищ данных. Этого не следует делать в Django. Вы должны использовать SQLAlchemy для хранения данных.
Для вашего конкретного практического руководства вы должны сделать это следующим образом:
MyModel.objects.values_list('column1', flat=True).distinct()
Но другие плакаты правильно говорят, что вы не должны думать, «как мне написать этот SQL в ORM». Когда вы изучали Python, исходя из Java, C ++ или чего-то еще, вы скоро научились отказываться от мышления «как мне написать этот Java-код на Python» и просто сосредоточились на решении проблемы с помощью Python. То же самое следует сказать и об использовании ORM.