mirror of
https://github.com/Infinidat/infi.clickhouse_orm.git
synced 2025-02-19 18:00:32 +03:00
1) Replaced is_insertable() field mehtod with readonly property (unification with model and tables)
2) Method SystemPart.all() was replaced with get() 3) Added conditions parameter to SystemPart.get() and SystemPart.get_active() methods.
This commit is contained in:
parent
58b7a9aeac
commit
5f2195f87f
23
README.rst
23
README.rst
|
@ -182,6 +182,29 @@ You can optionally pass conditions to the query::
|
|||
Note that ``order_by`` must be chosen so that the ordering is unique, otherwise there might be
|
||||
inconsistencies in the pagination (such as an instance that appears on two different pages).
|
||||
|
||||
System models
|
||||
-------------
|
||||
`Clickhouse docs <https://clickhouse.yandex/reference_en.html#System tables>`
|
||||
System models are read only models for implementing part of the system's functionality,
|
||||
and for providing access to information about how the system is working.
|
||||
|
||||
Usage example:
|
||||
|
||||
>>>> from infi.clickhouse_orm import system_models
|
||||
>>>> print(system_models.SystemPart.all())
|
||||
|
||||
Currently the fllowing system models are supported:
|
||||
|
||||
=================== ======== ================= ===================================================
|
||||
Class DB Table Pythonic Type Comments
|
||||
=================== ======== ================= ===================================================
|
||||
SystemPart
|
||||
|
||||
Partitions and parts
|
||||
--------------------
|
||||
`ClickHouse docs <https://clickhouse.yandex/reference_en.html#Manipulations with partitions and parts>`
|
||||
|
||||
|
||||
Schema Migrations
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -70,8 +70,9 @@ class Field(object):
|
|||
else:
|
||||
return self.db_type
|
||||
|
||||
def is_insertable(self):
|
||||
return self.alias is None and self.materialized is None
|
||||
@property
|
||||
def readonly(self):
|
||||
return self.alias is not None or self.materialized is not None
|
||||
|
||||
|
||||
class StringField(Field):
|
||||
|
|
|
@ -159,9 +159,8 @@ class Model(with_metaclass(ModelBase)):
|
|||
:param bool insertable_only: If True, returns only fields, that can be inserted into database
|
||||
'''
|
||||
data = self.__dict__
|
||||
fields = self._fields
|
||||
if insertable_only:
|
||||
fields = [f for f in fields if f[1].is_insertable()]
|
||||
|
||||
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)
|
||||
|
||||
def to_dict(self, insertable_only=False, field_names=None):
|
||||
|
@ -170,7 +169,7 @@ class Model(with_metaclass(ModelBase)):
|
|||
:param bool insertable_only: If True, returns only fields, that can be inserted into database
|
||||
:param field_names: An iterable of field names to return
|
||||
'''
|
||||
fields = [f for f in self._fields if f[1].is_insertable()] if insertable_only else self._fields
|
||||
fields = [f for f in self._fields if not f[1].readonly] if insertable_only else self._fields
|
||||
if field_names is not None:
|
||||
fields = [f for f in fields if f[0] in field_names]
|
||||
|
||||
|
|
|
@ -113,25 +113,30 @@ class SystemPart(Model):
|
|||
return self._partition_operation_sql(database, 'FETCH', settings=settings, from_part=zookeeper_path)
|
||||
|
||||
@classmethod
|
||||
def get_active(cls, database):
|
||||
def get(cls, database, conditions=""):
|
||||
"""
|
||||
Get all active parts
|
||||
Get all data from system.parts table
|
||||
:param database: A database object to fetch data from.
|
||||
:param conditions: WHERE clause conditions. Database condition is added automatically
|
||||
:return: A list of SystemPart objects
|
||||
"""
|
||||
assert isinstance(database, Database), "database must be database.Database class instance"
|
||||
assert isinstance(conditions, str), "conditions must be a string"
|
||||
if conditions:
|
||||
conditions += " AND"
|
||||
field_names = ','.join([f[0] for f in cls._fields])
|
||||
return database.select("SELECT %s FROM %s WHERE active AND database='%s'" %
|
||||
(field_names, cls.table_name(), database.db_name), model_class=cls)
|
||||
return database.select("SELECT %s FROM %s WHERE %s database='%s'" %
|
||||
(field_names, cls.table_name(), conditions, database.db_name), model_class=cls)
|
||||
|
||||
@classmethod
|
||||
def all(cls, database):
|
||||
def get_active(cls, database, conditions=""):
|
||||
"""
|
||||
Gets all data from system.parts database
|
||||
:param database:
|
||||
:return:
|
||||
Gets active data from system.parts table
|
||||
:param database: A database object to fetch data from.
|
||||
:param conditions: WHERE clause conditions. Database and active conditions are added automatically
|
||||
:return: A list of SystemPart objects
|
||||
"""
|
||||
assert isinstance(database, Database), "database must be database.Database class instance"
|
||||
field_names = ','.join([f[0] for f in cls._fields])
|
||||
return database.select("SELECT %s FROM %s WHERE database='%s'" %
|
||||
(field_names, cls.table_name(), database.db_name), model_class=cls)
|
||||
if conditions:
|
||||
conditions += ' AND '
|
||||
conditions += 'active'
|
||||
return SystemPart.get(database, conditions=conditions)
|
||||
|
|
|
@ -26,7 +26,7 @@ class SystemPartTest(unittest.TestCase):
|
|||
return dirnames
|
||||
|
||||
def test_get_all(self):
|
||||
parts = SystemPart.all(self.database)
|
||||
parts = SystemPart.get(self.database)
|
||||
self.assertEqual(len(list(parts)), 1)
|
||||
|
||||
def test_get_active(self):
|
||||
|
@ -35,6 +35,12 @@ class SystemPartTest(unittest.TestCase):
|
|||
parts[0].detach(self.database)
|
||||
self.assertEqual(len(list(SystemPart.get_active(self.database))), 0)
|
||||
|
||||
def test_get_conditions(self):
|
||||
parts = list(SystemPart.get(self.database, conditions="table='testtable'"))
|
||||
self.assertEqual(len(parts), 1)
|
||||
parts = list(SystemPart.get(self.database, conditions="table='othertable'"))
|
||||
self.assertEqual(len(parts), 0)
|
||||
|
||||
def test_attach_detach(self):
|
||||
parts = list(SystemPart.get_active(self.database))
|
||||
self.assertEqual(len(parts), 1)
|
||||
|
@ -49,7 +55,7 @@ class SystemPartTest(unittest.TestCase):
|
|||
self.assertEqual(len(list(SystemPart.get_active(self.database))), 0)
|
||||
|
||||
def test_freeze(self):
|
||||
parts = list(SystemPart.all(self.database))
|
||||
parts = list(SystemPart.get(self.database))
|
||||
# There can be other backups in the folder
|
||||
prev_backups = set(self._get_backups())
|
||||
parts[0].freeze(self.database)
|
||||
|
|
Loading…
Reference in New Issue
Block a user