Найти - Пользователи
Полная версия: Фильтрация queryset по нескольким таблицам средствами queryset.extra()
Начало » Django » Фильтрация queryset по нескольким таблицам средствами queryset.extra()
1
botinag
Помогите с формированием запроса к базе средствами 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'Остап Бендер'])

как это сделать лучше и правильнее? Моя писанина сильно тормозит
FishHook
Правильнее сделать raw-sql запрос.
botinag
У меня в модели Transaction уникальность гарантирует только связка из нескольких полей. Т.е. нет ни одного подходящего поля в которое можно прописать primary_key=True. Для работы с raw, на сколько я понимаю, необходим первичный ключ. Да и на выходе мне нужен queryset для дальнейших манипуляций…
Может все таки есть способы через queryset.extra() все это дело заставить корректно работать?
FishHook
botinag
Для работы с raw, на сколько я понимаю, необходим первичный ключ
Да с чего вдруг? raw он на то и raw, что там чистый как слеза девственницы sql, джойни по чему угодно.
botinag
и на выходе мне нужен queryset для дальнейших манипуляций…
это каких таких манипуляций?
botinag
Вообще передо мной стоит задача правильно отфильтрованные транзакции вывести в удобную таблицу с помощью 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
FishHook
botinag
вывести в удобную таблицу с помощью django-tables2
Хосспаде, зачем????? Возьмите любой JS-grid и работайте в рамках концепции MVC. За такие велосипеды надо лишать прав человека.
botinag
модифицировал модель транзакций
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 у меня хуже чем с питоном.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB