Как сделать объединение нескольких наборов запросов из ORM Clickhouse - PullRequest
1 голос
/ 05 июня 2019

В поисковом приложении Django я хочу запросить базу данных clickhouse (используя библиотеку infi.clickhouse_orm) для пар значений, таких как (a = 1 AND b> = 1.5) OR (a = 2 AND b> = 1 ). В SQL это можно сделать с помощью

select * from table where a == 1 and b >= 1.5 UNION ALL select * from table where a == 2 and b >= 1

Глядя на другие примеры, которые я пробовал:

С набором запросов, определенным как

qs = TABLE.objects_in(db)
qs_1 = qs.filter(A__eq=1, B__gte=1.5)
qs_2 = qs.filter(A__eq=2, B__gte=1)

| оператор

qs_union = qs_1 | qs_2

, который возвращает

unsupported operand type(s) for |: 'QuerySet' and 'QuerySet'

Оператор UNION

qs_union = qs_1.union(qs_2)

, который возвращает

'QuerySet' object has no attribute 'union'

и объекты Q

qs_union = qs.filter(Q(A__eq=1, B__gte=1.5) | Q(A__eq=2, B__gte=1))

, который возвращает

'Q' object has no attribute 'to_sql'

Как из моделей clickhouse вы выполняете набор из 2 или более наборов запросов?

Спасибо!

1 Ответ

0 голосов
/ 05 июня 2019

Краткий ответ : вы должны использовать Q класс infi.clickhouse_orm.query, например:

from infi.clickhouse_orm.query import <b>Q</b>

Q -класс в info.clickhouse_orm [GitHub] имеет метод to_sql:

class Q(object):

    # ...

    def to_sql(self, model_cls):
        if self._fovs:
            sql = ' {} '.format(self._mode).join(fov.to_sql(model_cls) for fov in self._fovs)
        else:
            if self._l_child and self._r_child:
                sql = '({} {} {})'.format(
                        self._l_child.to_sql(model_cls), self._mode, self._r_child.to_sql(model_cls))
            else:
                return '1'
        if self._negate:
            sql = 'NOT (%s)' % sql
        return sql

Так как в ошибках сказано, что он не может найти to_sql, похоже, вы не использовали этот Q -класс, но класс Джанго Q.

...