2017-01-26 13:42:33 +03:00
|
|
|
import unittest
|
|
|
|
from datetime import date
|
|
|
|
|
|
|
|
from infi.clickhouse_orm.database import Database
|
2020-02-08 13:05:48 +03:00
|
|
|
from infi.clickhouse_orm.models import Model, NO_VALUE
|
2017-01-26 13:42:33 +03:00
|
|
|
from infi.clickhouse_orm.fields import *
|
|
|
|
from infi.clickhouse_orm.engines import *
|
2020-05-01 20:11:40 +03:00
|
|
|
from infi.clickhouse_orm.funcs import F
|
2017-01-26 13:42:33 +03:00
|
|
|
|
|
|
|
|
2019-10-27 20:47:59 +03:00
|
|
|
class AliasFieldsTest(unittest.TestCase):
|
2017-01-26 13:42:33 +03:00
|
|
|
|
|
|
|
def setUp(self):
|
2019-06-13 08:12:56 +03:00
|
|
|
self.database = Database('test-db', log_statements=True)
|
2017-01-26 13:42:33 +03:00
|
|
|
self.database.create_table(ModelWithAliasFields)
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
self.database.drop_database()
|
|
|
|
|
|
|
|
def test_insert_and_select(self):
|
|
|
|
instance = ModelWithAliasFields(
|
|
|
|
date_field='2016-08-30',
|
|
|
|
int_field=-10,
|
|
|
|
str_field='TEST'
|
|
|
|
)
|
|
|
|
self.database.insert([instance])
|
|
|
|
# We can't select * from table, as it doesn't select materialized and alias fields
|
2019-10-27 20:47:59 +03:00
|
|
|
query = 'SELECT date_field, int_field, str_field, alias_int, alias_date, alias_str, alias_func' \
|
2017-01-26 13:42:33 +03:00
|
|
|
' FROM $db.%s ORDER BY alias_date' % ModelWithAliasFields.table_name()
|
|
|
|
for model_cls in (ModelWithAliasFields, None):
|
|
|
|
results = list(self.database.select(query, model_cls))
|
2018-08-19 18:22:22 +03:00
|
|
|
self.assertEqual(len(results), 1)
|
|
|
|
self.assertEqual(results[0].date_field, instance.date_field)
|
|
|
|
self.assertEqual(results[0].int_field, instance.int_field)
|
|
|
|
self.assertEqual(results[0].str_field, instance.str_field)
|
|
|
|
self.assertEqual(results[0].alias_int, instance.int_field)
|
|
|
|
self.assertEqual(results[0].alias_str, instance.str_field)
|
|
|
|
self.assertEqual(results[0].alias_date, instance.date_field)
|
2020-05-29 12:53:14 +03:00
|
|
|
self.assertEqual(results[0].alias_func, 201608)
|
2017-01-26 13:42:33 +03:00
|
|
|
|
|
|
|
def test_assignment_error(self):
|
|
|
|
# I can't prevent assigning at all, in case db.select statements with model provided sets model fields.
|
|
|
|
instance = ModelWithAliasFields()
|
|
|
|
for value in ('x', [date.today()], ['aaa'], [None]):
|
|
|
|
with self.assertRaises(ValueError):
|
|
|
|
instance.alias_date = value
|
|
|
|
|
2017-01-27 08:42:37 +03:00
|
|
|
def test_wrong_field(self):
|
|
|
|
with self.assertRaises(AssertionError):
|
|
|
|
StringField(alias=123)
|
|
|
|
|
|
|
|
def test_duplicate_default(self):
|
|
|
|
with self.assertRaises(AssertionError):
|
|
|
|
StringField(alias='str_field', default='with default')
|
|
|
|
|
|
|
|
with self.assertRaises(AssertionError):
|
|
|
|
StringField(alias='str_field', materialized='str_field')
|
|
|
|
|
2020-02-08 13:05:48 +03:00
|
|
|
def test_default_value(self):
|
|
|
|
instance = ModelWithAliasFields()
|
|
|
|
self.assertEqual(instance.alias_str, NO_VALUE)
|
2020-05-28 23:02:55 +03:00
|
|
|
# Check that NO_VALUE can be assigned to a field
|
|
|
|
instance.str_field = NO_VALUE
|
|
|
|
# Check that NO_VALUE can be assigned when creating a new instance
|
|
|
|
instance2 = ModelWithAliasFields(**instance.to_dict())
|
2020-02-08 13:05:48 +03:00
|
|
|
|
2017-01-26 13:42:33 +03:00
|
|
|
|
|
|
|
class ModelWithAliasFields(Model):
|
|
|
|
int_field = Int32Field()
|
|
|
|
date_field = DateField()
|
|
|
|
str_field = StringField()
|
|
|
|
|
2017-06-06 18:00:15 +03:00
|
|
|
alias_str = StringField(alias=u'str_field')
|
2017-01-27 08:42:37 +03:00
|
|
|
alias_int = Int32Field(alias='int_field')
|
|
|
|
alias_date = DateField(alias='date_field')
|
2020-05-29 12:53:14 +03:00
|
|
|
alias_func = Int32Field(alias=F.toYYYYMM(date_field))
|
2017-01-26 13:42:33 +03:00
|
|
|
|
|
|
|
engine = MergeTree('date_field', ('date_field',))
|