mirror of
https://github.com/Infinidat/infi.clickhouse_orm.git
synced 2024-11-22 09:06:41 +03:00
Merge branch 'carrotquest-qs-final' into develop
This commit is contained in:
commit
50f1fed187
|
@ -117,6 +117,17 @@ Adds a DISTINCT clause to the query, meaning that any duplicate rows in the resu
|
||||||
>>> Person.objects_in(database).only('first_name').distinct().count()
|
>>> Person.objects_in(database).only('first_name').distinct().count()
|
||||||
94
|
94
|
||||||
|
|
||||||
|
Final
|
||||||
|
--------
|
||||||
|
|
||||||
|
This method can be used only with CollapsingMergeTree engine.
|
||||||
|
Adds a FINAL modifier to the query, meaning data is selected fully "collapsed" by sign field.
|
||||||
|
|
||||||
|
>>> Person.objects_in(database).count()
|
||||||
|
100
|
||||||
|
>>> Person.objects_in(database).final().count()
|
||||||
|
94
|
||||||
|
|
||||||
Slicing
|
Slicing
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import pytz
|
import pytz
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from math import ceil
|
from math import ceil
|
||||||
|
|
||||||
|
from .engines import CollapsingMergeTree
|
||||||
from .utils import comma_join
|
from .utils import comma_join
|
||||||
|
|
||||||
|
|
||||||
|
@ -243,6 +246,7 @@ class QuerySet(object):
|
||||||
self._fields = model_cls.fields().keys()
|
self._fields = model_cls.fields().keys()
|
||||||
self._limits = None
|
self._limits = None
|
||||||
self._distinct = False
|
self._distinct = False
|
||||||
|
self._final = False
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""
|
"""
|
||||||
|
@ -290,9 +294,10 @@ class QuerySet(object):
|
||||||
fields = comma_join('`%s`' % field for field in self._fields)
|
fields = comma_join('`%s`' % field for field in self._fields)
|
||||||
ordering = '\nORDER BY ' + self.order_by_as_sql() if self._order_by else ''
|
ordering = '\nORDER BY ' + self.order_by_as_sql() if self._order_by else ''
|
||||||
limit = '\nLIMIT %d, %d' % self._limits if self._limits else ''
|
limit = '\nLIMIT %d, %d' % self._limits if self._limits else ''
|
||||||
params = (distinct, fields, self._model_cls.table_name(),
|
final = ' FINAL' if self._final else ''
|
||||||
|
params = (distinct, fields, self._model_cls.table_name(), final,
|
||||||
self.conditions_as_sql(), ordering, limit)
|
self.conditions_as_sql(), ordering, limit)
|
||||||
return u'SELECT %s%s\nFROM `%s`\nWHERE %s%s%s' % params
|
return u'SELECT %s%s\nFROM `%s`%s\nWHERE %s%s%s' % params
|
||||||
|
|
||||||
def order_by_as_sql(self):
|
def order_by_as_sql(self):
|
||||||
"""
|
"""
|
||||||
|
@ -399,6 +404,18 @@ class QuerySet(object):
|
||||||
qs._distinct = True
|
qs._distinct = True
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
def final(self):
|
||||||
|
"""
|
||||||
|
Adds a FINAL modifier to table, meaning data will be collapsed to final version.
|
||||||
|
Can be used with CollapsingMergeTree engine only
|
||||||
|
"""
|
||||||
|
if not isinstance(self._model_cls.engine, CollapsingMergeTree):
|
||||||
|
raise TypeError('final() method can be used only with CollapsingMergeTree engine')
|
||||||
|
|
||||||
|
qs = copy(self)
|
||||||
|
qs._final = True
|
||||||
|
return qs
|
||||||
|
|
||||||
def aggregate(self, *args, **kwargs):
|
def aggregate(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns an `AggregateQuerySet` over this query, with `args` serving as
|
Returns an `AggregateQuerySet` over this query, with `args` serving as
|
||||||
|
|
|
@ -148,4 +148,4 @@ data = [
|
||||||
{"first_name": "Whitney", "last_name": "Scott", "birthday": "1971-07-04", "height": "1.70"},
|
{"first_name": "Whitney", "last_name": "Scott", "birthday": "1971-07-04", "height": "1.70"},
|
||||||
{"first_name": "Wynter", "last_name": "Garcia", "birthday": "1975-01-10", "height": "1.69"},
|
{"first_name": "Wynter", "last_name": "Garcia", "birthday": "1975-01-10", "height": "1.69"},
|
||||||
{"first_name": "Yolanda", "last_name": "Duke", "birthday": "1997-02-25", "height": "1.74"}
|
{"first_name": "Yolanda", "last_name": "Duke", "birthday": "1997-02-25", "height": "1.74"}
|
||||||
];
|
]
|
||||||
|
|
|
@ -141,6 +141,20 @@ class QuerySetTestCase(TestCaseWithData):
|
||||||
SampleModel(timestamp=now, num=4, color=Color.white),
|
SampleModel(timestamp=now, num=4, color=Color.white),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def _insert_sample_collapsing_model(self):
|
||||||
|
self.database.create_table(SampleCollapsingModel)
|
||||||
|
now = datetime.now()
|
||||||
|
self.database.insert([
|
||||||
|
SampleCollapsingModel(timestamp=now, num=1, color=Color.red),
|
||||||
|
SampleCollapsingModel(timestamp=now, num=2, color=Color.red),
|
||||||
|
SampleCollapsingModel(timestamp=now, num=2, color=Color.red, sign=-1),
|
||||||
|
SampleCollapsingModel(timestamp=now, num=2, color=Color.green),
|
||||||
|
SampleCollapsingModel(timestamp=now, num=3, color=Color.white),
|
||||||
|
SampleCollapsingModel(timestamp=now, num=4, color=Color.white, sign=1),
|
||||||
|
SampleCollapsingModel(timestamp=now, num=4, color=Color.white, sign=-1),
|
||||||
|
SampleCollapsingModel(timestamp=now, num=4, color=Color.blue, sign=1),
|
||||||
|
])
|
||||||
|
|
||||||
def test_filter_enum_field(self):
|
def test_filter_enum_field(self):
|
||||||
self._insert_sample_model()
|
self._insert_sample_model()
|
||||||
qs = SampleModel.objects_in(self.database)
|
qs = SampleModel.objects_in(self.database)
|
||||||
|
@ -249,6 +263,17 @@ class QuerySetTestCase(TestCaseWithData):
|
||||||
self._test_qs(qs[70:80], 10)
|
self._test_qs(qs[70:80], 10)
|
||||||
self._test_qs(qs[80:], 20)
|
self._test_qs(qs[80:], 20)
|
||||||
|
|
||||||
|
def test_final(self):
|
||||||
|
# Final can be used with CollapsingMergeTree engine only
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
Person.objects_in(self.database).final()
|
||||||
|
|
||||||
|
self._insert_sample_collapsing_model()
|
||||||
|
res = list(SampleCollapsingModel.objects_in(self.database).final().order_by('num'))
|
||||||
|
self.assertEqual(4, len(res))
|
||||||
|
for item, exp_color in zip(res, (Color.red, Color.green, Color.white, Color.blue)):
|
||||||
|
self.assertEqual(exp_color, item.color)
|
||||||
|
|
||||||
|
|
||||||
class AggregateTestCase(TestCaseWithData):
|
class AggregateTestCase(TestCaseWithData):
|
||||||
|
|
||||||
|
@ -392,6 +417,13 @@ class SampleModel(Model):
|
||||||
engine = MergeTree('materialized_date', ('materialized_date',))
|
engine = MergeTree('materialized_date', ('materialized_date',))
|
||||||
|
|
||||||
|
|
||||||
|
class SampleCollapsingModel(SampleModel):
|
||||||
|
|
||||||
|
sign = Int8Field(default=1)
|
||||||
|
|
||||||
|
engine = CollapsingMergeTree('materialized_date', ('num',), 'sign')
|
||||||
|
|
||||||
|
|
||||||
class Numbers(Model):
|
class Numbers(Model):
|
||||||
|
|
||||||
number = UInt64Field()
|
number = UInt64Field()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user