mirror of
https://github.com/Infinidat/infi.clickhouse_orm.git
synced 2024-11-10 19:36:33 +03:00
Finished Release v1.0.1
This commit is contained in:
commit
238fd11d6b
|
@ -1,6 +1,12 @@
|
|||
Change Log
|
||||
==========
|
||||
|
||||
v1.0.1
|
||||
------
|
||||
- NullableField: take extra_null_values into account in `validate` and `to_python`
|
||||
- Added `Field.isinstance` method
|
||||
- Validate the inner field passed to `ArrayField`
|
||||
|
||||
v1.0.0
|
||||
------
|
||||
- Add support for compound filters with Q objects (desile)
|
||||
|
|
|
@ -5,7 +5,6 @@ download-cache = .cache
|
|||
develop = .
|
||||
parts =
|
||||
relative-paths = true
|
||||
extensions = buildout.wheel
|
||||
|
||||
[project]
|
||||
name = infi.clickhouse_orm
|
||||
|
|
|
@ -82,6 +82,8 @@ class SensorData(models.Model):
|
|||
data = SensorData(date=date.today(), temperatures=[25.5, 31.2, 28.7], humidity_levels=[41, 39, 66])
|
||||
```
|
||||
|
||||
Note that multidimensional arrays are not supported yet by the ORM.
|
||||
|
||||
Working with materialized and alias fields
|
||||
------------------------------------------
|
||||
|
||||
|
|
|
@ -79,6 +79,22 @@ class Field(object):
|
|||
else:
|
||||
return self.db_type
|
||||
|
||||
def isinstance(self, types):
|
||||
"""
|
||||
Checks if the instance if one of the types provided or if any of the inner_field child is one of the types
|
||||
provided, returns True if field or any inner_field is one of ths provided, False otherwise
|
||||
:param types: Iterable of types to check inclusion of instance
|
||||
:return: Boolean
|
||||
"""
|
||||
if isinstance(self, types):
|
||||
return True
|
||||
inner_field = getattr(self, 'inner_field', None)
|
||||
while inner_field:
|
||||
if isinstance(inner_field, types):
|
||||
return True
|
||||
inner_field = getattr(inner_field, 'inner_field', None)
|
||||
return False
|
||||
|
||||
|
||||
class StringField(Field):
|
||||
|
||||
|
@ -347,6 +363,8 @@ class ArrayField(Field):
|
|||
class_default = []
|
||||
|
||||
def __init__(self, inner_field, default=None, alias=None, materialized=None, readonly=None):
|
||||
assert isinstance(inner_field, Field), "The first argument of ArrayField must be a Field instance"
|
||||
assert not isinstance(inner_field, ArrayField), "Multidimensional array fields are not supported by the ORM"
|
||||
self.inner_field = inner_field
|
||||
super(ArrayField, self).__init__(default, alias, materialized, readonly)
|
||||
|
||||
|
@ -385,12 +403,12 @@ class NullableField(Field):
|
|||
super(NullableField, self).__init__(default, alias, materialized, readonly=None)
|
||||
|
||||
def to_python(self, value, timezone_in_use):
|
||||
if value == '\\N' or value is None:
|
||||
if value == '\\N' or value in self._null_values:
|
||||
return None
|
||||
return self.inner_field.to_python(value, timezone_in_use)
|
||||
|
||||
def validate(self, value):
|
||||
value is None or self.inner_field.validate(value)
|
||||
value in self._null_values or self.inner_field.validate(value)
|
||||
|
||||
def to_db_string(self, value, quote=True):
|
||||
if value in self._null_values:
|
||||
|
@ -398,5 +416,4 @@ class NullableField(Field):
|
|||
return self.inner_field.to_db_string(value, quote=quote)
|
||||
|
||||
def get_sql(self, with_default_expression=True):
|
||||
from .utils import escape
|
||||
return 'Nullable(%s)' % self.inner_field.get_sql(with_default_expression=False)
|
||||
|
|
|
@ -21,7 +21,7 @@ class ArrayFieldsTest(unittest.TestCase):
|
|||
instance = ModelWithArrays(
|
||||
date_field='2016-08-30',
|
||||
arr_str=['goodbye,', 'cruel', 'world', 'special chars: ,"\\\'` \n\t\\[]'],
|
||||
arr_date=['2010-01-01']
|
||||
arr_date=['2010-01-01'],
|
||||
)
|
||||
self.database.insert([instance])
|
||||
query = 'SELECT * from $db.modelwitharrays ORDER BY date_field'
|
||||
|
@ -62,6 +62,11 @@ class ArrayFieldsTest(unittest.TestCase):
|
|||
with self.assertRaises(ValueError):
|
||||
parse_array(s)
|
||||
|
||||
def test_invalid_inner_field(self):
|
||||
for x in (DateField, None, "", ArrayField(Int32Field())):
|
||||
with self.assertRaises(AssertionError):
|
||||
ArrayField(x)
|
||||
|
||||
|
||||
class ModelWithArrays(Model):
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ class MigrationsTestCase(unittest.TestCase):
|
|||
# Adding, removing and altering simple fields
|
||||
self.assertEquals(self.getTableFields(Model1), [('date', 'Date'), ('f1', 'Int32'), ('f2', 'String')])
|
||||
self.database.migrate('tests.sample_migrations', 4)
|
||||
self.assertEquals(self.getTableFields(Model2), [('date', 'Date'), ('f1', 'Int32'), ('f3', 'Float32'), ('f2', 'String'), ('f4', 'String')])
|
||||
self.assertEquals(self.getTableFields(Model2), [('date', 'Date'), ('f1', 'Int32'), ('f3', 'Float32'), ('f2', 'String'), ('f4', 'String'), ('f5', 'Array(UInt64)')])
|
||||
self.database.migrate('tests.sample_migrations', 5)
|
||||
self.assertEquals(self.getTableFields(Model3), [('date', 'Date'), ('f1', 'Int64'), ('f3', 'Float64'), ('f4', 'String')])
|
||||
# Altering enum fields
|
||||
|
@ -121,6 +121,7 @@ class Model2(Model):
|
|||
f3 = Float32Field()
|
||||
f2 = StringField()
|
||||
f4 = StringField()
|
||||
f5 = ArrayField(UInt64Field()) # addition of an array field
|
||||
|
||||
engine = MergeTree('date', ('date',))
|
||||
|
||||
|
|
|
@ -73,6 +73,22 @@ class NullableFieldsTest(unittest.TestCase):
|
|||
else:
|
||||
self.assertEquals(python_value, value)
|
||||
|
||||
def test_isinstance(self):
|
||||
for field in (StringField, UInt8Field, Float32Field, DateTimeField):
|
||||
f = NullableField(field())
|
||||
self.assertTrue(f.isinstance(field))
|
||||
self.assertTrue(f.isinstance(NullableField))
|
||||
for field in (Int8Field, Int16Field, Int32Field, Int64Field, UInt8Field, UInt16Field, UInt32Field, UInt64Field):
|
||||
f = NullableField(field())
|
||||
self.assertTrue(f.isinstance(BaseIntField))
|
||||
for field in (Float32Field, Float64Field):
|
||||
f = NullableField(field())
|
||||
self.assertTrue(f.isinstance(BaseFloatField))
|
||||
f = NullableField(NullableField(UInt32Field()))
|
||||
self.assertTrue(f.isinstance(BaseIntField))
|
||||
self.assertTrue(f.isinstance(NullableField))
|
||||
self.assertFalse(f.isinstance(BaseFloatField))
|
||||
|
||||
def _insert_sample_data(self):
|
||||
dt = date(1970, 1, 1)
|
||||
self.database.insert([
|
||||
|
|
Loading…
Reference in New Issue
Block a user