mirror of
https://github.com/Infinidat/infi.clickhouse_orm.git
synced 2025-07-10 16:12:26 +03:00
Fixed:
1) Added partition working to readme 2) replaced insertable_only parameter with include_readonly 3) Added empty string alias and materialized field control
This commit is contained in:
parent
27217102da
commit
14f2ab78b5
10
README.rst
10
README.rst
|
@ -193,8 +193,14 @@ and for providing access to information about how the system is working.
|
||||||
|
|
||||||
Usage example::
|
Usage example::
|
||||||
|
|
||||||
>>>> from infi.clickhouse_orm import system_models
|
from infi.clickhouse_orm.database import Database
|
||||||
>>>> print(system_models.SystemPart.get(Database()))
|
from infi.clickhouse_orm.system_models import SystemPart
|
||||||
|
db = Database('my_test_db', db_url='http://192.168.1.1:8050', username='scott', password='tiger')
|
||||||
|
partitions = SystemPart.get_active(db, conditions='') # Getting all active partitions of the database
|
||||||
|
if len(partitions) > 0:
|
||||||
|
partitions = sorted(partitions, key=lambda obj: obj.name) # Partition name is YYYYMM, so we can sort so
|
||||||
|
partitions[0].freeze(db) # Make a backup in /opt/clickhouse/shadow directory
|
||||||
|
partitions[0].drop() # Dropped partition
|
||||||
|
|
||||||
Currently the following system models are supported:
|
Currently the following system models are supported:
|
||||||
|
|
||||||
|
|
|
@ -62,11 +62,11 @@ class Database(object):
|
||||||
|
|
||||||
def gen():
|
def gen():
|
||||||
yield self._substitute('INSERT INTO $table FORMAT TabSeparated\n', model_class).encode('utf-8')
|
yield self._substitute('INSERT INTO $table FORMAT TabSeparated\n', model_class).encode('utf-8')
|
||||||
yield (first_instance.to_tsv(insertable_only=True) + '\n').encode('utf-8')
|
yield (first_instance.to_tsv(include_readonly=False) + '\n').encode('utf-8')
|
||||||
# Collect lines in batches of batch_size
|
# Collect lines in batches of batch_size
|
||||||
batch = []
|
batch = []
|
||||||
for instance in i:
|
for instance in i:
|
||||||
batch.append(instance.to_tsv(insertable_only=True))
|
batch.append(instance.to_tsv(include_readonly=False))
|
||||||
if len(batch) >= batch_size:
|
if len(batch) >= batch_size:
|
||||||
# Return the current batch of lines
|
# Return the current batch of lines
|
||||||
yield ('\n'.join(batch) + '\n').encode('utf-8')
|
yield ('\n'.join(batch) + '\n').encode('utf-8')
|
||||||
|
|
|
@ -16,8 +16,10 @@ class Field(object):
|
||||||
def __init__(self, default=None, alias=None, materialized=None):
|
def __init__(self, default=None, alias=None, materialized=None):
|
||||||
assert (None, None) in {(default, alias), (alias, materialized), (default, materialized)}, \
|
assert (None, None) in {(default, alias), (alias, materialized), (default, materialized)}, \
|
||||||
"Only one of default, alias and materialized parameters can be given"
|
"Only one of default, alias and materialized parameters can be given"
|
||||||
assert alias is None or isinstance(alias, str), "Alias field must be string field name, if given"
|
assert alias is None or isinstance(alias, str) and alias != "",\
|
||||||
assert materialized is None or isinstance(materialized, str), "Materialized field must be string, if given"
|
"Alias field must be string field name, if given"
|
||||||
|
assert materialized is None or isinstance(materialized, str) and alias != "",\
|
||||||
|
"Materialized field must be string, if given"
|
||||||
|
|
||||||
self.creation_counter = Field.creation_counter
|
self.creation_counter = Field.creation_counter
|
||||||
Field.creation_counter += 1
|
Field.creation_counter += 1
|
||||||
|
@ -72,7 +74,7 @@ class Field(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def readonly(self):
|
def readonly(self):
|
||||||
return self.alias is not None or self.materialized is not None
|
return bool(self.alias or self.materialized)
|
||||||
|
|
||||||
|
|
||||||
class StringField(Field):
|
class StringField(Field):
|
||||||
|
|
|
@ -153,26 +153,25 @@ class Model(with_metaclass(ModelBase)):
|
||||||
kwargs[name] = field.to_python(next(values), timezone_in_use)
|
kwargs[name] = field.to_python(next(values), timezone_in_use)
|
||||||
return cls(**kwargs)
|
return cls(**kwargs)
|
||||||
|
|
||||||
def to_tsv(self, insertable_only=False):
|
def to_tsv(self, include_readonly=True):
|
||||||
'''
|
'''
|
||||||
Returns the instance's column values as a tab-separated line. A newline is not included.
|
Returns the instance's column values as a tab-separated line. A newline is not included.
|
||||||
:param bool insertable_only: If True, returns only fields, that can be inserted into database
|
:param bool include_readonly: If False, returns only fields, that can be inserted into database
|
||||||
'''
|
'''
|
||||||
data = self.__dict__
|
data = self.__dict__
|
||||||
|
fields = self._fields if include_readonly else [f for f in self._fields if not f[1].readonly]
|
||||||
fields = [f for f in self._fields if not f[1].readonly] if insertable_only else self._fields
|
|
||||||
return '\t'.join(field.to_db_string(data[name], quote=False) for name, field in fields)
|
return '\t'.join(field.to_db_string(data[name], quote=False) for name, field in fields)
|
||||||
|
|
||||||
def to_dict(self, insertable_only=False, field_names=None, timezone_in_use=pytz.utc):
|
def to_dict(self, include_readonly=True, field_names=None):
|
||||||
'''
|
'''
|
||||||
Returns the instance's column values as a dict.
|
Returns the instance's column values as a dict.
|
||||||
:param bool insertable_only: If True, returns only fields, that can be inserted into database
|
:param bool include_readonly: If False, returns only fields, that can be inserted into database
|
||||||
:param field_names: An iterable of field names to return
|
:param field_names: An iterable of field names to return
|
||||||
:param timezone_in_use: timezone to convert DateField and DateTimeField.
|
|
||||||
'''
|
'''
|
||||||
fields = [f for f in self._fields if not f[1].readonly] if insertable_only else self._fields
|
fields = self._fields if include_readonly else [f for f in self._fields if not f[1].readonly]
|
||||||
|
|
||||||
if field_names is not None:
|
if field_names is not None:
|
||||||
fields = [f for f in fields if f[0] in field_names]
|
fields = [f for f in fields if f[0] in field_names]
|
||||||
|
|
||||||
data = self.__dict__
|
data = self.__dict__
|
||||||
return {name: field.to_python(data[name], timezone_in_use) for name, field in fields}
|
return {name: data[name] for name, field in fields}
|
||||||
|
|
|
@ -65,7 +65,7 @@ class ModelTestCase(unittest.TestCase):
|
||||||
"alias_field": 0.0,
|
"alias_field": 0.0,
|
||||||
'str_field': 'dozo'
|
'str_field': 'dozo'
|
||||||
})
|
})
|
||||||
self.assertDictEqual(instance.to_dict(insertable_only=True), {
|
self.assertDictEqual(instance.to_dict(include_readonly=False), {
|
||||||
"date_field": datetime.date(1973, 12, 6),
|
"date_field": datetime.date(1973, 12, 6),
|
||||||
"int_field": 100,
|
"int_field": 100,
|
||||||
"float_field": 7.0,
|
"float_field": 7.0,
|
||||||
|
@ -73,7 +73,7 @@ class ModelTestCase(unittest.TestCase):
|
||||||
'str_field': 'dozo'
|
'str_field': 'dozo'
|
||||||
})
|
})
|
||||||
self.assertDictEqual(
|
self.assertDictEqual(
|
||||||
instance.to_dict(insertable_only=True, field_names=('int_field', 'alias_field', 'datetime_field')), {
|
instance.to_dict(include_readonly=False, field_names=('int_field', 'alias_field', 'datetime_field')), {
|
||||||
"int_field": 100,
|
"int_field": 100,
|
||||||
"datetime_field": datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=pytz.utc)
|
"datetime_field": datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=pytz.utc)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user