LINUX.ORG.RU

django ORM-выборка из двух не связанных таблиц одновременно

 ,


0

1

имеются две таблицы:

mysql> select * from t1;
+------+------+
| x    | y    |
+------+------+
|    1 |    2 |
|    2 |    3 |
+------+------+

mysql> select * from t2;
+------+------+
| x    | z    |
+------+------+
|    1 |    4 |
|    3 |    5 |
+------+------+

нужно сделать вот такую выборку, не прибегая к SQL:

mysql> SELECT t1.y,t2.z  FROM t1,t2 where t1.x=t2.x;
+------+------+
| y    | z    |
+------+------+
|    2 |    4 |
+------+------+

в одном query set это врядли возможно (если T1 и T2 и правда никак не связаны через модели). Только если в 2:

    q1 = T1.objects.filter(x__in=T2.objects.values('x').distinct()).values('x', 'y')
    q2 = T2.objects.filter(x__in=T1.objects.values('x').distinct()).values('x', 'z')
И потом программно их сджоинить по x

du_hast
()
Ответ на: комментарий от du_hast

А вообще, если X общий для этих моделей, то тогда его стоить вынести в отдельную модель-справочник. После этого, думаю, можно будет в один query set делать запрос через annotate

du_hast
()
Ответ на: комментарий от du_hast

Да, отличное поколение растет. ТС, вот признайся, только честно, ты пробовал гуглить?

anonymous
()
Ответ на: комментарий от du_hast

А что еще джанго орм не умеет искаропки? Ай-ай-ай.. А как сделать кастомный запрос (ну например сразу в 3-4 таблицы с джойнами и аггрегацией) а потом корректно присвоить результат модельке, и все это не руками, а где-то под капотом, чтоб само? Где почитать про такие финты?

deep-purple ★★★★★
()

нужно сделать вот такую выборку, не прибегая к SQL:

Я в андроиде забил на всякие ContentValues и высокоуровневые обертки и дергаю напрямую rawQuery, чего и вас советую.

crowbar
()
Ответ на: комментарий от deep-purple

А что еще джанго орм не умеет искаропки?

много чего, она довольно примитивная, и её разработчики этого не скрывают

А как сделать кастомный запрос (ну например сразу в 3-4 таблицы с джойнами и аггрегацией) а потом корректно присвоить результат модельке, и все это не руками, а где-то под капотом, чтоб само?

Все зависит от моделей и их связей. Можно и такое, но само все равно ничего не бывает =)

Где почитать про такие финты?

много чего есть в джанговском багтрекере :)

du_hast
()
Последнее исправление: du_hast (всего исправлений: 1)
Ответ на: комментарий от django2014

так и есть, x береться из отдельного справочника.

тогда все должно быть просто, нужно только почитать про annotate :-)

du_hast
()
Ответ на: комментарий от du_hast

Гуглил и читал документацию (djbook), в частности про аннотацию. Теоретически понятно, что annotate аннотирует объект аггрегированным значение. В доках и гугле вычисляется среднее, максимальное, минимальное, количество записей ... это все работает.

Но, нихрена не понятно, как в параметрах аннотации обратиться к другой таблице

например, из таблицы 1 я выбираю все, мне нужные записи со значения поля x из списка list_x

T1.objects.filter(x_id__in=list_x).annotate(Как здесь проаннотировать записи выборками из T2)

django2014
() автор топика
Ответ на: комментарий от django2014

не знаю что там с annotate, но задача решается и через extra(select={'t2__z':<путь_к_полю_z_в_t2>}, tables=[<имя таблицы от модели t2>], where=['условие связи']). имена полей и таблиц можно вытащить из _meta моделей.

anon1984
()
Ответ на: комментарий от django2014

X не должен быть в таком случае (если нужны такого рода запросы) списком. Можно и без всяких выкрутасов, если X не список, а модель:

X.objects.filter(t1__isnull=False,t2__isnull=False).values('t1__y', 't2__z')

du_hast
()
Последнее исправление: du_hast (всего исправлений: 1)
Ответ на: комментарий от du_hast

du_hast, извини за мою тупость, но не пойму я как сделать выборку за раз, без сырого SQL или extra ... но очень хочеться разобраться

У меня есть такие модели

  • User (стандартное auth_user),
  • Профиль пользователя Profile
  • Данные какие-то Data
from django.contrib.auth.models import User
class Profile(models.Model):
    login = models.ForeignKey(User, unique=True)
    first_name = models.CharField(u'First name',max_length=200)
    middle_name = models.CharField(u'Middle name',max_length=200)
    def __unicode__(self):
        return '%s %s ' % (self.first_name,  self.middle_name)

class Data(models.Model):
    login =  models.ForeignKey(User)
    f = models.PositiveIntegerField(u'f', default=2)
    def __unicode__(self):
        return str(self.f)

например, мне нужно выбрать данные, в которых f=4 и 10, все просто:

In [14]: Data.objects.filter(f__in=[4,10]).values('login','f')
Out[14]: [{'login': 3L, 'f': 10L}, {'login': 2L, 'f': 4L}]

но при этом мне нужны не логины пользователя, а их имена-отчества:

In [12]: User.objects.all()
Out[12]: [<User: ivan>, <User: user1>, <User: user2>]

In [13]: Profile.objects.all()
Out[13]: [<Profile: Марья  Ивановна >, <Profile: Сергей  Сергеевич >]

django2014
() автор топика
Ответ на: комментарий от django2014
Data.objects.filter(f__in=[4,10]).values('login__first_name', 'login__last_name','f')

так?

Edit: вот так

Data.objects.filter(f__in=[4,10]).values('login__profile__first_name', 'login__profile__middle_name','f')

du_hast
()
Последнее исправление: du_hast (всего исправлений: 2)
Ответ на: комментарий от django2014

Пожалуйста. Нужно в вопросе сразу выкладывать по возможности всё, что есть, чтобы получить то, чего хочется :) Чтобы не пришлось выпытывать)

du_hast
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.