"""Contains utility classes to persist :class:`dataclasses.dataclass`."""__author__='Paul Landes'fromtypingimportType,List,Tuple,Any,ClassVarfromdataclassesimportdataclass,field,fieldsimportdataclassesimportloggingfromstringimportTemplatefrompathlibimportPathfrom.importDynamicDataParser,BeanDbPersister,Beanlogger=logging.getLogger(__name__)
[docs]classDataClassDynamicDataParser(DynamicDataParser):"""An SQL data parser that replaces ``${cols}`` in the SQL file with the :class:`dataclasses.dataclass` fields. :see: :class:`.DataClassDbPersister` """ID_FIELD:ClassVar[str]='id'"""The name of the column that has the unique identifier of the row/object. """
[docs]def__init__(self,dd_path:Path,bean_class:Type):super().__init__(dd_path)ifnotdataclasses.is_dataclass(bean_class):raiseValueError(f'not a dataclass: {bean_class}')cols=map(lambdaf:f.name,dataclasses.fields(bean_class))cols=', '.join(filter(lambdac:c!=self.ID_FIELD,cols))iflogger.isEnabledFor(logging.DEBUG):logger.debug(f'cols: {cols}')self.context={'cols':cols}
[docs]@dataclassclassDataClassDbPersister(BeanDbPersister):"""Persists instances of :class:`dataclasses.dataclass` by narrowing the columns from select statements. Instead of ``select *``, use ``select ${cols}`` in the SQL resource file. :see: :class:`.DataClassDynamicDataParser` """bean_class:Type[dataclass]=field(default=None)"""The data class that is CRUD'd for DB operations."""def__post_init__(self):self.row_factory=self.bean_classsuper().__post_init__()def_create_parser(self,sql_file:Path)->DynamicDataParser:returnDataClassDynamicDataParser(sql_file,self.bean_class)def_get_insert_row(self,bean:Bean)->Tuple[Any]:idf=DataClassDynamicDataParser.ID_FIELDreturntuple(map(lambdaf:getattr(bean,f.name),filter(lambdaf:f.name!=idf,fields(bean))))