четверг, 24 декабря 2009 г.

Человечный SQL

Джанга всегда славилась удобством из коробки, но как только тебе надо чуть больше, чем положено, начинается гемор...
Хороший пример это sql запрос, который стандартный ORM не позволял составить.
Правда, не буду лукавить, есть 2 метода запихивания своего sql в запрос:
  1. Обращение к базе минуя ORM
    connect.cursor().execute('SELECT * FROM `person`;')
    Большим минусом является, то что на выходе у нас список списков, а не объектов нужной нам модели.
  2. Дополнение запроса от ORM
    Books.objects.filter(pages__gte=123).extra(select={'result': 'SUM(cost)'})
    Тут минус - в ограниченности.
Правда, сейчас extra почти не нужен, его земенил annotate.
Но вселенского счастья все равно не наступило )

И тут, ВНЕЗАПНО... ревизия 11921 и Model.objects.raw офигеть! )

Raw как раз, то что нужно в ситуации: "блин, ну как, ну как это впихнуть в этот уг ORM"
Джанга сама замапит результат выборки на модель, плюс можно добавить агрегацию.
А недостающие поля (разумеется кроме primary key), при обращении к ним, будут подсасываться из базы на лету.
Ну и пример:
>>>Person.objects.raw('SELECT * from myapp_person')[<person: doe="" john="">, <person: doe="" jane="">, ...]
В общем, надеюсь ,теперь станет проще, в ситуациях когда требуется особо хитрая сортировка c агрегацией по join'у, ну или... (придумай сам)

Только народ, помни, что добавленный в конце слайс, нифига не сработает как ожидается...
Это будет не limit с offsec'том, а обычный слайс по списку.

И еще один нюанс, raw это метод manager'а, а не queryset'а. Т.е.
Model.object.all().raw(...) работать не будет.

А, все таки, хочется надеяться, что мир станет идеальным и можно будет обойтись Model.object.all().delete )

Комментариев нет:

Отправить комментарий