mirror of
https://github.com/Infinidat/infi.clickhouse_orm.git
synced 2024-09-21 11:18:55 +03:00
Add support for FixedString fields
This commit is contained in:
parent
2b8c0b6c38
commit
dbea017d60
|
@ -252,6 +252,7 @@ Currently the following field types are supported:
|
|||
Class DB Type Pythonic Type Comments
|
||||
=================== ======== ================= ===================================================
|
||||
StringField String unicode Encoded as UTF-8 when written to ClickHouse
|
||||
FixedStringField String unicode Encoded as UTF-8 when written to ClickHouse
|
||||
DateField Date datetime.date Range 1970-01-01 to 2038-01-19
|
||||
DateTimeField DateTime datetime.datetime Minimal value is 1970-01-01 00:00:00; Always in UTC
|
||||
Int8Field Int8 int Range -128 to 127
|
||||
|
|
|
@ -90,6 +90,24 @@ class StringField(Field):
|
|||
raise ValueError('Invalid value for %s: %r' % (self.__class__.__name__, value))
|
||||
|
||||
|
||||
class FixedStringField(StringField):
|
||||
|
||||
def __init__(self, length, default=None, alias=None, materialized=None):
|
||||
self._length = length
|
||||
self.db_type = 'FixedString(%d)' % length
|
||||
super(FixedStringField, self).__init__(default, alias, materialized)
|
||||
|
||||
def to_python(self, value, timezone_in_use):
|
||||
value = super(FixedStringField, self).to_python(value, timezone_in_use)
|
||||
return value.rstrip('\0')
|
||||
|
||||
def validate(self, value):
|
||||
if isinstance(value, text_type):
|
||||
value = value.encode('UTF-8')
|
||||
if len(value) > self._length:
|
||||
raise ValueError('Value of %d bytes is too long for FixedStringField(%d)' % (len(value), self._length))
|
||||
|
||||
|
||||
class DateField(Field):
|
||||
|
||||
min_value = datetime.date(1970, 1, 1)
|
||||
|
|
|
@ -58,6 +58,10 @@ class ModelBase(type):
|
|||
if db_type.startswith('Array'):
|
||||
inner_field = cls.create_ad_hoc_field(db_type[6 : -1])
|
||||
return orm_fields.ArrayField(inner_field)
|
||||
# FixedString
|
||||
if db_type.startswith('FixedString'):
|
||||
length = int(db_type[12 : -1])
|
||||
return orm_fields.FixedStringField(length)
|
||||
# Simple fields
|
||||
name = db_type + 'Field'
|
||||
if not hasattr(orm_fields, name):
|
||||
|
|
58
tests/test_fixed_string_fields.py
Normal file
58
tests/test_fixed_string_fields.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unittest
|
||||
|
||||
from infi.clickhouse_orm.database import Database
|
||||
from infi.clickhouse_orm.models import Model
|
||||
from infi.clickhouse_orm.fields import *
|
||||
from infi.clickhouse_orm.engines import *
|
||||
|
||||
|
||||
class FixedStringFieldsTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.database = Database('test-db')
|
||||
self.database.create_table(FixedStringModel)
|
||||
|
||||
def tearDown(self):
|
||||
self.database.drop_database()
|
||||
|
||||
def _insert_sample_data(self):
|
||||
self.database.insert([
|
||||
FixedStringModel(date_field='2016-08-30', fstr_field=''),
|
||||
FixedStringModel(date_field='2016-08-30'),
|
||||
FixedStringModel(date_field='2016-08-31', fstr_field='foo'),
|
||||
FixedStringModel(date_field='2016-08-31', fstr_field=u'לילה')
|
||||
])
|
||||
|
||||
def _assert_sample_data(self, results):
|
||||
self.assertEquals(len(results), 4)
|
||||
self.assertEquals(results[0].fstr_field, '')
|
||||
self.assertEquals(results[1].fstr_field, 'ABCDEFGHIJK')
|
||||
self.assertEquals(results[2].fstr_field, 'foo')
|
||||
self.assertEquals(results[3].fstr_field, u'לילה')
|
||||
|
||||
def test_insert_and_select(self):
|
||||
self._insert_sample_data()
|
||||
query = 'SELECT * from $table ORDER BY date_field'
|
||||
results = list(self.database.select(query, FixedStringModel))
|
||||
self._assert_sample_data(results)
|
||||
|
||||
def test_ad_hoc_model(self):
|
||||
self._insert_sample_data()
|
||||
query = 'SELECT * from $db.fixedstringmodel ORDER BY date_field'
|
||||
results = list(self.database.select(query))
|
||||
self._assert_sample_data(results)
|
||||
|
||||
def test_assignment_error(self):
|
||||
for value in (17, 'this is too long', u'זה ארוך', None, 99.9):
|
||||
with self.assertRaises(ValueError):
|
||||
FixedStringModel(fstr_field=value)
|
||||
|
||||
|
||||
class FixedStringModel(Model):
|
||||
|
||||
date_field = DateField()
|
||||
fstr_field = FixedStringField(12, default='ABCDEFGHIJK')
|
||||
|
||||
engine = MergeTree('date_field', ('date_field',))
|
Loading…
Reference in New Issue
Block a user