Комментарии 8
И прав, и не прав. ORM не может быть независимым от БД. Это обёртка, прослойка, которая представляет запросы к БД и их результат в форме, специфичной для языка программирования. Об этом само название говорит. Object Related Model. Т.е. представление модели в виде объектов языка.
Кроме-того, независимость ORM от БД нужна не для того, чтобы каждый день менять этот движок. Разработчики в условиях реальной работы выбирают одну БД и под неё пишут. Запросы оптимизируются, часто пишется чистый SQL. Но вот его использовать не желательно. Поскольку, это другой язык. У тебя весь код на Python, вся архитектура представлена объектами и функциями. А тут раз, и переход на SQL. Как минимум, это не красиво. Как максимум — не безопасно. А в общих чертах: если ты возьмёшь полученный запрос и попытаешься его выполнить, ты автоматически выйдешь за рамки операций с QuerySet, Lazy Connection и т.д. ты добавляешь в свой код ещё одну сущность: raw SQL.
Кроме-того, независимость ORM от БД нужна не для того, чтобы каждый день менять этот движок. Разработчики в условиях реальной работы выбирают одну БД и под неё пишут. Запросы оптимизируются, часто пишется чистый SQL. Но вот его использовать не желательно. Поскольку, это другой язык. У тебя весь код на Python, вся архитектура представлена объектами и функциями. А тут раз, и переход на SQL. Как минимум, это не красиво. Как максимум — не безопасно. А в общих чертах: если ты возьмёшь полученный запрос и попытаешься его выполнить, ты автоматически выйдешь за рамки операций с QuerySet, Lazy Connection и т.д. ты добавляешь в свой код ещё одну сущность: raw SQL.
вообще-то ORM — Object-Relational Mapping
<zanuda-mode-off />
<zanuda-mode-off />
Но это чисто логическое и стилевое ограничение. Разумеется, если тебе нужно сделать что-то особое, ты выполняешь SQL. Но не тогда, когда ORM поддерживает функционал. Иначе зачем вообще ORM? Можно было бы с тем же успехом выполнять SQL запросы вместо Model.objects.all()
Код, написанный с использованием ORM намного короче и красивее, легче читается, модифицируется и его намного проще использовать повторно.
Кроме того, в большинстве случаев он достаточно хорошо переносим. Зависимости от конкретной базы появляются в достаточно сложных случаях, и это обычно уже та ситуация, когда о миграции на другую базу никто даже не задумывается.
Я тоже согласен, что код на ORM не так лаконичен. Однако, следует понять для чего вообще используется ORM. А используется он для того, чтобы вынести все SQL операции в чёрный ящик, предоставив разработчику возможность работы только с объектами. Допустим, у нас нет ORM (разработчики Django решили отказаться от него). Что мы будем делать? Наша задача — найти и прикрутить существующую ORM, либо написать свою. Причин для этого много. В частности, мы не захотим постоянно выполнять запросы к БД и производить типизацию полученных значений. Скорее-всего, мы создадим нечто подобное тому, что есть сейчас. А именно, определим абстракции для таблиц, напишем для них обёртку, которая будет получать из БД данные и превращать их в свойства объекта. Реализуем паттерн Lazy connection. Т.е., по факту, создадим заново ORM для джанги.
Итак, в начале и прежде-всего, ORM реализует работу с объектами и классами, исключая наше вмешательство в исполнение запросов и препроцессинг/постпроцессинг данных. Однако, возникают ситуации, подобные описанной в треде. И у нас возникает дилемма: либо мы вводим в нашу объектно-ориентированную архитектуру построения данных SQL костыли, либо пытаемся реализовать запрос на уровне ORM. В любом случае, костыль на SQL актуален только тогда, когда без него система не сможет работать. Например, у нас Django < 1.8. У нас есть выбор: реализовать запрос с помощью SQL, либо:
И, как ни странно, именно этот вариант будет правильным до тех пор, пока код не начнёт исполняться слишком долго. Даже такое решение позволяет избавиться от инжекта чужеродного кода в скрипт.
Итак, в начале и прежде-всего, ORM реализует работу с объектами и классами, исключая наше вмешательство в исполнение запросов и препроцессинг/постпроцессинг данных. Однако, возникают ситуации, подобные описанной в треде. И у нас возникает дилемма: либо мы вводим в нашу объектно-ориентированную архитектуру построения данных SQL костыли, либо пытаемся реализовать запрос на уровне ORM. В любом случае, костыль на SQL актуален только тогда, когда без него система не сможет работать. Например, у нас Django < 1.8. У нас есть выбор: реализовать запрос с помощью SQL, либо:
def extract_number(username):
# Code here
numbers = [extract_number(username) for username in User.objects.filter(username__iregex=r'^KZ\d+$').values_list('username', flat=True)]
И, как ни странно, именно этот вариант будет правильным до тех пор, пока код не начнёт исполняться слишком долго. Даже такое решение позволяет избавиться от инжекта чужеродного кода в скрипт.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Нескучные запросы с Django ORM Annotate и Query Expressions