django - вести к ORM для пользователей SQL?

django имеет этот сложный ORM, встроенный к нему, но после проведения большого количества времени на нем, мне все еще трудно сделать запросы, которые удивительно просты в SQL. Существуют даже некоторые простые вещи, которые я не могу найти способ сделать через django ORM (например, 'выбирают отличный column1 из имени таблицы').

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

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

9
задан sienkiew 4 February 2010 в 19:47
поделиться

4 ответа

Есть некоторые вещи, которые до смешного просты в 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-запросов .

8
ответ дан 4 December 2019 в 10:32
поделиться

Хорошей отправной точкой для выполнения запросов 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')

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

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

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

4
ответ дан 4 December 2019 в 10:32
поделиться

Подумайте об этом способ.

«Что я должен был делать в первую очередь для обычных обходов 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 для хранения данных.

6
ответ дан 4 December 2019 в 10:32
поделиться

Для вашего конкретного практического руководства вы должны сделать это следующим образом:

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

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

2
ответ дан 4 December 2019 в 10:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: