From 8959a84fed941a2cfb8c7f6ed67c9ad46d48d9f4 Mon Sep 17 00:00:00 2001 From: lyssom <569810240@qq.com> Date: Wed, 19 May 2021 10:32:19 +0800 Subject: [PATCH 1/3] support having --- src/infi/clickhouse_orm/query.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/infi/clickhouse_orm/query.py b/src/infi/clickhouse_orm/query.py index 92efec4..c34376a 100644 --- a/src/infi/clickhouse_orm/query.py +++ b/src/infi/clickhouse_orm/query.py @@ -295,6 +295,7 @@ def __init__(self, model_cls, database): self._model_cls = model_cls self._database = database self._order_by = [] + self._having = '' self._where_q = Q() self._prewhere_q = Q() self._grouping_fields = [] @@ -392,6 +393,9 @@ def as_sql(self): if self._grouping_with_totals: sql += ' WITH TOTALS' + if self._having: + sql += '\nhaving ' + self.having_as_sql() + if self._order_by: sql += '\nORDER BY ' + self.order_by_as_sql() @@ -413,6 +417,12 @@ def order_by_as_sql(self): for field in self._order_by ]) + def having_as_sql(self): + """ + Returns the contents of the query's `Having` clause as a string. + """ + return self._having + def conditions_as_sql(self, prewhere=False): """ Returns the contents of the query's `WHERE` or `PREWHERE` clause as a string. @@ -442,6 +452,14 @@ def order_by(self, *field_names): qs._order_by = field_names return qs + def having(self, having_str): + """ + Returns a copy of this queryset with the having changed. + """ + qs = copy(self) + qs._having = having_str + return qs + def only(self, *field_names): """ Returns a copy of this queryset limited to the specified field names. From 274e0103fa0497ac89cb5c912cbc0c662e8d26d5 Mon Sep 17 00:00:00 2001 From: lyssom <569810240@qq.com> Date: Thu, 20 May 2021 09:13:18 +0800 Subject: [PATCH 2/3] use HAVING --- src/infi/clickhouse_orm/query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/infi/clickhouse_orm/query.py b/src/infi/clickhouse_orm/query.py index c34376a..010276c 100644 --- a/src/infi/clickhouse_orm/query.py +++ b/src/infi/clickhouse_orm/query.py @@ -394,7 +394,7 @@ def as_sql(self): sql += ' WITH TOTALS' if self._having: - sql += '\nhaving ' + self.having_as_sql() + sql += '\nHAVING ' + self.having_as_sql() if self._order_by: sql += '\nORDER BY ' + self.order_by_as_sql() From 25f76833a3655395e5cd2224ee82707c7e96632e Mon Sep 17 00:00:00 2001 From: lyssom <569810240@qq.com> Date: Wed, 26 May 2021 14:40:03 +0800 Subject: [PATCH 3/3] use Q function support having --- src/infi/clickhouse_orm/query.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/infi/clickhouse_orm/query.py b/src/infi/clickhouse_orm/query.py index 010276c..53927a0 100644 --- a/src/infi/clickhouse_orm/query.py +++ b/src/infi/clickhouse_orm/query.py @@ -452,12 +452,24 @@ def order_by(self, *field_names): qs._order_by = field_names return qs - def having(self, having_str): + def having(self, *q, **kwargs): """ - Returns a copy of this queryset with the having changed. + Returns a copy of this queryset that includes only rows matching the having conditions. """ + qs = copy(self) - qs._having = having_str + + condition = Q() + for arg in q: + if isinstance(arg, Q): + condition &= arg + else: + raise TypeError('Invalid argument "%r" to queryset filter' % arg) + + if kwargs: + condition &= Q(**kwargs) + + qs._having = condition.to_sql(self._model_cls) return qs def only(self, *field_names):