Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Фильтрация queryset по нескольким таблицам средствами queryset.extra() [RSS Feed]

#1 Май 28, 2015 11:19:45

botinag
Зарегистрирован: 2014-02-20
Сообщения: 179
Репутация: +  35  -
Профиль   Отправить e-mail  

Фильтрация queryset по нескольким таблицам средствами queryset.extra()

Помогите с формированием запроса к базе средствами django. Необходимо получить queryset, содержащий все транзакции (Transaction) у которых владелец (Owner) клиента (Client) = Остап Бендер

Так выглядят модели:

class Transaction(models.Model):
    id = models.IntegerField(db_column='id')  # <-- Тут id из таблицы clientdetails, но не всегда
    ...много полей...
 
    class Meta:
        managed = False
        db_table = 'transactions'
 
class Client(models.Model):
    id = models.IntegerField(db_column='id', primary_key=True)
    name = models.CharField(db_column='name', max_length=50)
    ...много полей...
 
    class Meta:
        managed = False
        db_table = 'clientdetails'
 
class Owner(models.Model):
    name = models.CharField(db_column='name', max_length=40)  # <-- Тут name из clientdetails, но не всегда
    owner = models.CharField(db_column='owner', max_length=50) # <-- Тут много имен, среди которых нужен только Остап Бендер
    ...много полей...
 
    class Meta:
        managed = False
        db_table = 'owner'

вот такой корявый sql запрос у меня получился:

select transactions.* from transactions join (select clientdetails.id, owner.owner from clientdetails join owner on clientdetails.name = owner.name where owner.owner = 'Остап Бендер') as t on t.id = transactions.id

Вот так я сделал это средствами джанго:
Transaction.objects.extra(tables=['clientdetails', 'owner'],
                          where=[u'''transactions.id = clientdetails.id and
                                 clientdetails.name = owner.name and
                                 owner.owner = %s'''],
                          params=[u'Остап Бендер'])

как это сделать лучше и правильнее? Моя писанина сильно тормозит

Офлайн

#2 Май 28, 2015 11:35:17

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Фильтрация queryset по нескольким таблицам средствами queryset.extra()

Правильнее сделать raw-sql запрос.



Офлайн

#3 Май 28, 2015 11:51:59

botinag
Зарегистрирован: 2014-02-20
Сообщения: 179
Репутация: +  35  -
Профиль   Отправить e-mail  

Фильтрация queryset по нескольким таблицам средствами queryset.extra()

У меня в модели Transaction уникальность гарантирует только связка из нескольких полей. Т.е. нет ни одного подходящего поля в которое можно прописать primary_key=True. Для работы с raw, на сколько я понимаю, необходим первичный ключ. Да и на выходе мне нужен queryset для дальнейших манипуляций…
Может все таки есть способы через queryset.extra() все это дело заставить корректно работать?

Офлайн

#4 Май 28, 2015 11:57:17

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Фильтрация queryset по нескольким таблицам средствами queryset.extra()

botinag
Для работы с raw, на сколько я понимаю, необходим первичный ключ
Да с чего вдруг? raw он на то и raw, что там чистый как слеза девственницы sql, джойни по чему угодно.
botinag
и на выходе мне нужен queryset для дальнейших манипуляций…
это каких таких манипуляций?



Офлайн

#5 Май 28, 2015 14:05:31

botinag
Зарегистрирован: 2014-02-20
Сообщения: 179
Репутация: +  35  -
Профиль   Отправить e-mail  

Фильтрация queryset по нескольким таблицам средствами queryset.extra()

Вообще передо мной стоит задача правильно отфильтрованные транзакции вывести в удобную таблицу с помощью django-tables2.
Для этого я в своей вьюхе отнаследовался от SingleTableView и пытаюсь передать в качестве queryset

Transaction.objects.raw(u'''select transactions.* from transactions join (select clientdetails.id, owner.owner from clientdetails join owner on clientdetails.name = owner.name where owner.owner = 'Остап Бендер') as t on t.id = transactions.id''')
на что получаю ошибку
data must be QuerySet-like (have count and order_by) or support list(data) -- RawQuerySet has neither
Пытаюсь зайти с другой стороны. Хочу сформировать список из RawQuerySet, но при попытке формирования списка
[x.id for x in Transaction.objects.raw(u'''select transactions.* from transactions join (select clientdetails.id, owner.owner from clientdetails join owner on clientdetails.name = owner.name where owner.owner = 'Остап Бендер') as t on t.id = transactions.id''')]
получаю ошибку:
InvalidQuery: Raw query must include the primary key

Офлайн

#6 Май 28, 2015 15:40:46

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Фильтрация queryset по нескольким таблицам средствами queryset.extra()

botinag
вывести в удобную таблицу с помощью django-tables2
Хосспаде, зачем????? Возьмите любой JS-grid и работайте в рамках концепции MVC. За такие велосипеды надо лишать прав человека.



Офлайн

#7 Май 28, 2015 19:36:14

botinag
Зарегистрирован: 2014-02-20
Сообщения: 179
Репутация: +  35  -
Профиль   Отправить e-mail  

Фильтрация queryset по нескольким таблицам средствами queryset.extra()

модифицировал модель транзакций

class Transaction(models.Model):
    id = models.IntegerField(db_column='id', primary_key=True)  # <-- Тут id из таблицы clientdetails, но не всегда
    ...много полей...
 
    class Meta:
        managed = False
        db_table = 'transactions'
        unique_together = (('id', 'другие', 'поля''),)
теперь код
[x.id for x in Transaction.objects.raw(u'''select transactions.* from transactions join (select clientdetails.id, owner.owner from clientdetails join owner on clientdetails.name = owner.name where owner.owner = 'Остап Бендер') as t on t.id = transactions.id''')]
не выкидывает ошибок и получившийся список можно скормить django_tables2.
Но по прежнему стоит вопрос с производительностью запроса к базе. Буду думать дальше.

FishHook
Хосспаде, зачем?????
Для остальных моделей (без хитрых фильтраций queryset) настроил. Работает. Устраивает.
FishHook
Возьмите любой JS-grid и работайте в рамках концепции MVC
В будущем ознакомлюсь. С js у меня хуже чем с питоном.

Офлайн

  • Начало
  • » Django
  • » Фильтрация queryset по нескольким таблицам средствами queryset.extra()[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version