mirror of
https://github.com/Infinidat/infi.clickhouse_orm.git
synced 2024-11-22 09:06:41 +03:00
- Add log_statements
parameter to database initializer
- Fix test_merge which fails on ClickHouse v19.8.3
This commit is contained in:
parent
6a2509b96e
commit
9dd1a8f409
|
@ -11,6 +11,8 @@ Unreleased
|
||||||
- Use HTTP Basic Authentication instead of passing the credentials in the URL
|
- Use HTTP Basic Authentication instead of passing the credentials in the URL
|
||||||
- Support default/alias/materialized for nullable fields
|
- Support default/alias/materialized for nullable fields
|
||||||
- Add UUIDField (kpotehin)
|
- Add UUIDField (kpotehin)
|
||||||
|
- Add `log_statements` parameter to database initializer
|
||||||
|
- Fix test_merge which fails on ClickHouse v19.8.3
|
||||||
|
|
||||||
v1.0.4
|
v1.0.4
|
||||||
------
|
------
|
||||||
|
|
|
@ -83,7 +83,7 @@ class Database(object):
|
||||||
|
|
||||||
def __init__(self, db_name, db_url='http://localhost:8123/',
|
def __init__(self, db_name, db_url='http://localhost:8123/',
|
||||||
username=None, password=None, readonly=False, autocreate=True,
|
username=None, password=None, readonly=False, autocreate=True,
|
||||||
timeout=60, verify_ssl_cert=True):
|
timeout=60, verify_ssl_cert=True, log_statements=False):
|
||||||
'''
|
'''
|
||||||
Initializes a database instance. Unless it's readonly, the database will be
|
Initializes a database instance. Unless it's readonly, the database will be
|
||||||
created on the ClickHouse server if it does not already exist.
|
created on the ClickHouse server if it does not already exist.
|
||||||
|
@ -96,6 +96,7 @@ class Database(object):
|
||||||
- `autocreate`: automatically create the database if it does not exist (unless in readonly mode).
|
- `autocreate`: automatically create the database if it does not exist (unless in readonly mode).
|
||||||
- `timeout`: the connection timeout in seconds.
|
- `timeout`: the connection timeout in seconds.
|
||||||
- `verify_ssl_cert`: whether to verify the server's certificate when connecting via HTTPS.
|
- `verify_ssl_cert`: whether to verify the server's certificate when connecting via HTTPS.
|
||||||
|
- `log_statements`: when True, all database statements are logged.
|
||||||
'''
|
'''
|
||||||
self.db_name = db_name
|
self.db_name = db_name
|
||||||
self.db_url = db_url
|
self.db_url = db_url
|
||||||
|
@ -105,6 +106,7 @@ class Database(object):
|
||||||
self.request_session.verify = verify_ssl_cert
|
self.request_session.verify = verify_ssl_cert
|
||||||
if username:
|
if username:
|
||||||
self.request_session.auth = (username, password or '')
|
self.request_session.auth = (username, password or '')
|
||||||
|
self.log_statements = log_statements
|
||||||
self.settings = {}
|
self.settings = {}
|
||||||
self.db_exists = False # this is required before running _is_existing_database
|
self.db_exists = False # this is required before running _is_existing_database
|
||||||
self.db_exists = self._is_existing_database()
|
self.db_exists = self._is_existing_database()
|
||||||
|
@ -334,6 +336,8 @@ class Database(object):
|
||||||
def _send(self, data, settings=None, stream=False):
|
def _send(self, data, settings=None, stream=False):
|
||||||
if isinstance(data, string_types):
|
if isinstance(data, string_types):
|
||||||
data = data.encode('utf-8')
|
data = data.encode('utf-8')
|
||||||
|
if self.log_statements:
|
||||||
|
logger.info(data)
|
||||||
params = self._build_params(settings)
|
params = self._build_params(settings)
|
||||||
r = self.request_session.post(self.db_url, params=params, data=data, stream=stream, timeout=self.timeout)
|
r = self.request_session.post(self.db_url, params=params, data=data, stream=stream, timeout=self.timeout)
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
|
|
|
@ -311,9 +311,16 @@ class MergeModel(Model):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_table_sql(cls, db):
|
def create_table_sql(cls, db):
|
||||||
assert isinstance(cls.engine, Merge), "engine must be engines.Merge instance"
|
assert isinstance(cls.engine, Merge), "engine must be an instance of engines.Merge"
|
||||||
return super(MergeModel, cls).create_table_sql(db)
|
parts = ['CREATE TABLE IF NOT EXISTS `%s`.`%s` (' % (db.db_name, cls.table_name())]
|
||||||
|
cols = []
|
||||||
|
for name, field in iteritems(cls.fields()):
|
||||||
|
if name != '_table':
|
||||||
|
cols.append(' %s %s' % (name, field.get_sql()))
|
||||||
|
parts.append(',\n'.join(cols))
|
||||||
|
parts.append(')')
|
||||||
|
parts.append('ENGINE = ' + cls.engine.create_table_sql(db))
|
||||||
|
return '\n'.join(parts)
|
||||||
|
|
||||||
# TODO: base class for models that require specific engine
|
# TODO: base class for models that require specific engine
|
||||||
|
|
||||||
|
@ -324,7 +331,7 @@ class DistributedModel(Model):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def set_database(self, db):
|
def set_database(self, db):
|
||||||
assert isinstance(self.engine, Distributed), "engine must be engines.Distributed instance"
|
assert isinstance(self.engine, Distributed), "engine must be an instance of engines.Distributed"
|
||||||
res = super(DistributedModel, self).set_database(db)
|
res = super(DistributedModel, self).set_database(db)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ logging.getLogger("requests").setLevel(logging.WARNING)
|
||||||
class TestCaseWithData(unittest.TestCase):
|
class TestCaseWithData(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.create_table(Person)
|
self.database.create_table(Person)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
|
@ -11,7 +11,7 @@ from infi.clickhouse_orm.engines import *
|
||||||
class MaterializedFieldsTest(unittest.TestCase):
|
class MaterializedFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.create_table(ModelWithAliasFields)
|
self.database.create_table(ModelWithAliasFields)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
|
@ -11,7 +11,7 @@ from infi.clickhouse_orm.engines import *
|
||||||
class ArrayFieldsTest(unittest.TestCase):
|
class ArrayFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.create_table(ModelWithArrays)
|
self.database.create_table(ModelWithArrays)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
|
@ -9,7 +9,7 @@ from infi.clickhouse_orm.engines import Memory
|
||||||
class CustomFieldsTest(unittest.TestCase):
|
class CustomFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.database.drop_database()
|
self.database.drop_database()
|
||||||
|
|
|
@ -10,7 +10,7 @@ from infi.clickhouse_orm.engines import *
|
||||||
class DateFieldsTest(unittest.TestCase):
|
class DateFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.create_table(ModelWithDate)
|
self.database.create_table(ModelWithDate)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
|
@ -12,7 +12,7 @@ from infi.clickhouse_orm.engines import *
|
||||||
class DecimalFieldsTest(unittest.TestCase):
|
class DecimalFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.add_setting('allow_experimental_decimal_type', 1)
|
self.database.add_setting('allow_experimental_decimal_type', 1)
|
||||||
try:
|
try:
|
||||||
self.database.create_table(DecimalModel)
|
self.database.create_table(DecimalModel)
|
||||||
|
|
|
@ -14,7 +14,7 @@ logging.getLogger("requests").setLevel(logging.WARNING)
|
||||||
class _EnginesHelperTestCase(unittest.TestCase):
|
class _EnginesHelperTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.database.drop_database()
|
self.database.drop_database()
|
||||||
|
@ -115,8 +115,8 @@ class EnginesTestCase(_EnginesHelperTestCase):
|
||||||
TestModel2(date='2017-01-02', event_id=2, event_group=2, event_count=2, event_version=2)
|
TestModel2(date='2017-01-02', event_id=2, event_group=2, event_count=2, event_version=2)
|
||||||
])
|
])
|
||||||
# event_uversion is materialized field. So * won't select it and it will be zero
|
# event_uversion is materialized field. So * won't select it and it will be zero
|
||||||
res = self.database.select('SELECT *, event_uversion FROM $table ORDER BY event_id', model_class=TestMergeModel)
|
res = self.database.select('SELECT *, _table, event_uversion FROM $table ORDER BY event_id', model_class=TestMergeModel)
|
||||||
res = [row for row in res]
|
res = list(res)
|
||||||
self.assertEqual(2, len(res))
|
self.assertEqual(2, len(res))
|
||||||
self.assertDictEqual({
|
self.assertDictEqual({
|
||||||
'_table': 'testmodel1',
|
'_table': 'testmodel1',
|
||||||
|
|
|
@ -15,7 +15,7 @@ except NameError:
|
||||||
class EnumFieldsTest(unittest.TestCase):
|
class EnumFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.create_table(ModelWithEnum)
|
self.database.create_table(ModelWithEnum)
|
||||||
self.database.create_table(ModelWithEnumArray)
|
self.database.create_table(ModelWithEnumArray)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ from infi.clickhouse_orm.engines import *
|
||||||
class FixedStringFieldsTest(unittest.TestCase):
|
class FixedStringFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.create_table(FixedStringModel)
|
self.database.create_table(FixedStringModel)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
|
@ -9,7 +9,7 @@ from infi.clickhouse_orm import database, engines, fields, models
|
||||||
class JoinTest(unittest.TestCase):
|
class JoinTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = database.Database('test-db')
|
self.database = database.Database('test-db', log_statements=True)
|
||||||
self.database.create_table(Foo)
|
self.database.create_table(Foo)
|
||||||
self.database.create_table(Bar)
|
self.database.create_table(Bar)
|
||||||
self.database.insert([Foo(id=i) for i in range(3)])
|
self.database.insert([Foo(id=i) for i in range(3)])
|
||||||
|
|
|
@ -11,7 +11,7 @@ from infi.clickhouse_orm.engines import *
|
||||||
class MaterializedFieldsTest(unittest.TestCase):
|
class MaterializedFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.create_table(ModelWithMaterializedFields)
|
self.database.create_table(ModelWithMaterializedFields)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
|
@ -24,7 +24,7 @@ logging.getLogger("requests").setLevel(logging.WARNING)
|
||||||
class MigrationsTestCase(unittest.TestCase):
|
class MigrationsTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.drop_table(MigrationHistory)
|
self.database.drop_table(MigrationHistory)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
|
@ -14,7 +14,7 @@ from datetime import date, datetime
|
||||||
class NullableFieldsTest(unittest.TestCase):
|
class NullableFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.create_table(ModelWithNullable)
|
self.database.create_table(ModelWithNullable)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
|
@ -14,7 +14,7 @@ from infi.clickhouse_orm.system_models import SystemPart
|
||||||
|
|
||||||
class SystemTest(unittest.TestCase):
|
class SystemTest(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.database.drop_database()
|
self.database.drop_database()
|
||||||
|
@ -38,7 +38,7 @@ class SystemPartTest(unittest.TestCase):
|
||||||
BACKUP_DIRS = ['/var/lib/clickhouse/shadow', '/opt/clickhouse/shadow/']
|
BACKUP_DIRS = ['/var/lib/clickhouse/shadow', '/opt/clickhouse/shadow/']
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
self.database.create_table(TestTable)
|
self.database.create_table(TestTable)
|
||||||
self.database.create_table(CustomPartitionedTable)
|
self.database.create_table(CustomPartitionedTable)
|
||||||
self.database.insert([TestTable(date_field=date.today())])
|
self.database.insert([TestTable(date_field=date.today())])
|
||||||
|
|
|
@ -10,7 +10,7 @@ from infi.clickhouse_orm.engines import Memory
|
||||||
class UUIDFieldsTest(unittest.TestCase):
|
class UUIDFieldsTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.database = Database('test-db')
|
self.database = Database('test-db', log_statements=True)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.database.drop_database()
|
self.database.drop_database()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user