#!D:\IDE\Anaconda3\envs\Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
 @Author: Administrator
 @FileName: AppDBInterface.py
 @DateTime: 2025/6/21 22:31
 @SoftWare: PyCharm
 @Author  ：xsh
"""
from AppSettings.Settings import RECODE_SUCCEED, RECODE_FAILURE
from AppUtils.utils import *
from sqlalchemy.orm import Session
from sqlalchemy import func
from sqlalchemy import Engine, create_engine
from sqlalchemy.orm import (Relationship)
from sqlalchemy.orm.decl_api import DeclarativeBase
from AppInterfaces.DBManager import (dbController, DBManager)
class AppDBInterface:
    def initialize(self):
        self.initData       ()
        self.initValue      ()
        self.initProperty   ()
        self.initConnect    ()

    def deinitialize(self):
        self.deleConnect    ()
        self.deleProperty   ()
        self.deleValue      ()
        self.deleData       ()

    def initData(self):
        self.initSession()

    def deleData(self):
        self.Engine = None

    def initConnect(self):
        pass

    def deleConnect(self):
        pass

    def initValue(self):
        pass

    def deleValue(self):
        pass

    def initProperty(self):
        pass

    def deleProperty(self):
        pass

class DBInterface(AppDBInterface):
    __field__ = ()
    __types__ = ()

    @property
    def hasID(self) -> bool:
        return hasattr(self, 'ID') and self.ID is not None
    @classmethod
    def instance(cls, **args):
        result: cls = cls.__new__(cls)
        result.__init__(**args)
        return result

    @classmethod
    def Instance(cls, buffer: dict, **args):
        result: cls = cls.__new__(cls)
        result.__init__(**args)
        result.as_field(buffer)
        return result

    @classmethod
    def count(cls) -> int:
        count: int = 0
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                count = session.query(func.count(cls.ID)).scalar()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return count

    @classmethod
    def first(cls):
        item: cls
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).first()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
            item = cls.instance()
        return item

    @classmethod
    def changed(cls, data: dict, *filters):
        if isinstance(data, dict):
            try:
                dbController.initEngine()

                with Session(dbController.Engine) as session:
                    try:
                        if filters is None or len(filters) <= 0:
                            session.query(cls).update(data)
                        else:
                            session.query(cls).filter(*filters).update(data)
                        session.commit()
                    except Exception as commitEx:
                        AppUtils.print_Exception(commitEx)
                        session.rollback()
                    session.close()
            except Exception as e:
                from AppLog.logHelper import logDB
                logDB << AppUtils.toString(e)
        return

    def to_field(self, is_primary: bool = True) -> dict[str, object]:
        buffer: dict[str, object] = {}
        primary: str = ''
        try:
            primary = DBInterface.get_primary_name(self)
        except Exception as e:
            primary = ''

        for index, _property in enumerate(self.__field__):
            if is_primary:
                buffer[_property] = getattr(self, _property, None)
            else:
                if _property != primary:
                    buffer[_property] = getattr(self, _property, None)
        return buffer

    def to_save_field(self, is_primary: bool = True) -> dict[str, object]:
        buffer: dict[str, object] = {}
        primary: str = ''
        try:
            primary = DBInterface.get_primary_name(self)
        except Exception as e:
            primary = ''
        for index, _property in enumerate(self.__field__):
            if is_primary:
                buffer[_property] = getattr(self, _property, None)
            else:
                if _property != primary:
                    buffer[_property] = getattr(self, _property, None)
        return buffer

    def as_field(self, buffer: dict[str, object], is_primary: bool = True):
        primary: str
        index  : int
        try:
            primary = DBInterface.get_primary_name(self)
        except Exception as e:
            primary = ''
        keys: list[str] = list(buffer.keys())
        if not is_primary:
            if primary in keys:
                buffer.pop(primary)
        keys = list(buffer.keys())
        for index, _property in enumerate(self.__field__):
            if _property in keys:
                setattr(self, _property, AppConvert.ObjectConvert(buffer.get(_property, None), self.__types__[index]))


    def to_YAML(self) -> str:
        buffer: dict[str, object] = self.to_field()
        string: str = ''
        try:
            string = ConvertUtils.toYaml(buffer)
        except Exception as e:
            AppUtils.print_Exception(e)
        return string

    def to_TEXT(self) -> str:
        buffer: dict[str, object] = self.to_field()
        string: str = ''
        try:
            for key, value in buffer.items():
                string += f'{key}:{value}\r\n'
        except Exception as e:
            AppUtils.print_Exception(e)
        return string

    def to_JSON(self) -> str:
        buffer: dict[str, object] = self.to_field()
        string: str = ''
        try:
            string = ConvertUtils.toJson(buffer)
        except Exception as e:
            AppUtils.print_Exception(e)
        return string

    def toYAML(self, save_name: str):
        buffer: dict[str, object] = self.to_field()
        try:
            AppUtils.save_string_to_file(save_name, ConvertUtils.toYaml(buffer))
        except Exception as e:
            AppUtils.print_Exception(e)
        pass

    def toTEXT(self, save_name: str):
        buffer: dict[str, object] = self.to_field()
        string: str = ''
        try:
            for key, value in buffer.items():
                string += f'{key}:{value}\r\n'
            AppUtils.save_string_to_file(save_name, string)
        except Exception as e:
            AppUtils.print_Exception(e)
        pass

    def toJSON(self, save_name: str):
        buffer: dict[str, object] = self.to_field()
        try:

            AppUtils.save_string_to_file(save_name, ConvertUtils.toJson(buffer))
        except Exception as e:
            AppUtils.print_Exception(e)

        pass




    def save_info(self, filename: str, fmt: str):
        if fmt.lower() == 'yaml' or fmt.lower() == 'yam':
            self.toYAML(filename)
        elif fmt.lower() == 'json':
            self.toJSON(filename)
        else:
            self.toTEXT(filename)


    def from_field(self, buffer):
        keys: list[str] = []
        if isinstance(buffer, dict):
            keys = list(buffer.keys())
            if len(keys) <= 0:
                return
            for index, _property in enumerate(self.__field__):
                if _property in keys:
                    setattr(self, _property, AppConvert.ObjectConvert(buffer.get(_property), self.__types__[index]))
        elif type(buffer) == type(self):
            keys = [] if not hasattr(buffer, '__field__') else list(buffer.__field__)
            if len(keys) <= 0:
                return
            for index, _property in enumerate(self.__field__):
                if _property in keys:
                    setattr(self, _property, AppConvert.ObjectConvert(getattr(buffer, _property, None), self.__types__[index]))

    @staticmethod
    def has__dict__(buffer) -> bool:
        return hasattr(buffer, '__dict__')

    @staticmethod
    def to_DICT(self, is_primary: bool = True) -> dict[str, object]:
        buffer: dict[str, object] = {}
        keys: list[str] = DBInterface.get_orm_fields(self)
        primary: str = DBInterface.get_primary_name(self)
        for key in keys:
            try:
                if not is_primary:
                    if key == primary:
                        pass
                    else:
                        buffer[key] = getattr(self, key, None)
                else:
                    buffer[key] = getattr(self, key, None)
            except Exception as e:
                print(f'key: {key}')
                AppUtils.print_Exception(e)
        return buffer
    @staticmethod
    def to_DATA(self, is_primary: bool = True):
        buffer: dict[str, object] = {}
        keys: list[str] = DBInterface.get_orm_fields(self)
        primary: str = DBInterface.get_primary_name(self)
        for key in keys:
            try:
                if not is_primary:
                    if key == primary:
                        pass
                    else:
                        buffer[key] = getattr(self, key, None)
                else:
                    buffer[key] = getattr(self, key, None)
            except Exception as e:
                print(f'key: {key}')
                AppUtils.print_Exception(e)
        return buffer

    @staticmethod
    def set_orm_property(item: DeclarativeBase, key: str, value: object):
        try:
            setattr(item, key, value)
        except Exception as e:
            AppUtils.print_Exception(e)


    @staticmethod
    def set_orm_fields(self: DeclarativeBase, buffer: dict[str, object]):
        try:
            keys: list[str] = AppDBInterface.get_orm_fields(self)
            for _property, value in buffer:
                if _property in keys:
                    setattr(self, _property, buffer.get(_property, None))

        except Exception as e:
            AppUtils.print_Exception(e)

    @staticmethod
    def get_orm_fields(self: DeclarativeBase) -> list[str]:
        table_dicts = {i.name: i for i in self.metadata.tables.values()}
        return list(table_dicts[f'{self.__tablename__}'].c.keys())

    @staticmethod
    def get_primary_name(self: DeclarativeBase) -> str:
        primary_key_name: str = self.__table__.primary_key.columns.values()[0].name
        return primary_key_name


    def get_table_fields(self) -> list[str]:
        return self.get_orm_fields(self)

    def get_property_key(self) -> str:
        return self.get_primary_name(self)

    def set_property(self, key: str, value: object):
        self.set_orm_property(self, key, value)

    def get_property(self, key: str):
        return getattr(self, key, None)

    def initParameter(self, **args):
        keys: list[str] = list(args.keys())

        for index, _property in enumerate(self.__field__):
            if _property in keys:
                src_buffer = getattr(self, _property, None)
                if isinstance(src_buffer, DBInterface):
                    setattr(self, _property, args.get(_property, None))
                else:
                    setattr(self, _property, AppConvert.ObjectConvert(args.get(_property, None), self.__types__[index]))

    def serialize(self) -> dict[str, object]:
        buffer: dict[str, object] = {}
        src_buffer: object
        keys: list[str] = self.get_table_fields()
        for index, _property in enumerate(keys):
            src_buffer = getattr(self, _property, None)
            if isinstance(src_buffer, DeclarativeBase):
                buffer[f'{_property}'] = self.to_DATA(src_buffer)
            elif isinstance(src_buffer, DBInterface):
                buffer[f'{_property}'] = src_buffer.serialize()
            else:
                buffer[f'{_property}'] = src_buffer
        return buffer

    def deserialize(self, buffer: (dict, object)):
        if isinstance(buffer, dict):
            src_buffer: object
            for index, _property in enumerate(self.__field__):
                dst_buffer = getattr(buffer, _property, None)
                src_buffer = getattr(self, _property, None)
                if isinstance(dst_buffer, DeclarativeBase):
                    setattr(self, _property, dst_buffer)
                elif isinstance(dst_buffer, DBInterface):
                    setattr(self, _property, dst_buffer)
                else:
                    setattr(self, _property, AppConvert.ObjectConvert(src_buffer, self.__types__[index]))
        elif self.has__dict__(buffer):
            for index, _property in enumerate(self.__field__):
                dst_buffer = getattr(buffer, _property, None)
                if isinstance(dst_buffer, DeclarativeBase):
                    setattr(self, _property, dst_buffer)
                elif isinstance(dst_buffer, DBInterface):
                    setattr(self, _property, dst_buffer)
                else:
                    setattr(self, _property, AppConvert.ObjectConvert(dst_buffer, self.__types__[index]))


    def isEqual(self, other) -> bool:
        return True if other is not None and id(self) == id(other) else False

    def initialize(self):
        self.initData       ()
        self.initValue      ()
        self.initProperty   ()
        self.initConnect    ()

    def deinitialize(self):
        self.deleConnect    ()
        self.deleProperty   ()
        self.deleValue      ()
        self.deleData       ()

    def initData(self):
        pass

    def deleData(self):
        pass

    def initConnect(self):
        pass

    def deleConnect(self):
        pass

    def initValue(self):
        pass

    def deleValue(self):
        pass

    def initProperty(self):
        pass

    def deleProperty(self):
        pass

    @classmethod
    def get_model_fields(cls) -> list[str]:
        result: list[str] = [_property for _property, value in cls.__dict__.items() if hasattr(value, 'property') and isinstance(getattr(value, 'property'), Relationship)]
        return result

    @staticmethod
    def model_fields(self) -> list[str]:
        result: list[str] = [_property for _property, value in self.__class__.__dict__.items() if hasattr(value, 'property') and isinstance(getattr(value, 'property'), Relationship)]
        return result
    @property
    def has_Engine(self) -> bool:
        return hasattr(self, 'Engine') and isinstance(self.Engine, Engine)

    @property
    def engine(self) -> Engine:
        return None if not self.has_Engine else self.Engine

    def initEngine(self):
        if not self.has_Engine :
            from AppSettings.AppSetting import AppConfig
            self.Engine  = create_engine(AppConfig.DB.get_sqlalchemy_information(),echo=False,max_overflow=5)

    @classmethod
    def has_table(cls) -> bool:
        if not hasattr(cls, '__tablename__'):
            return False
        dbController.initEngine()
        has_table = dbController.Engine.dialect.has_table(dbController.Engine.connect(), cls.__tablename__)
        return has_table
    @classmethod
    def table_size(cls) -> int:
        if not hasattr(cls, '__tablename__'):
            return False
        dbController.initEngine()
        has_table = dbController.Engine.dialect.has_table(dbController.Engine.connect(), cls.__tablename__)
        if not has_table:
            return False
        Primary = 0
        try:
            dbController.initEngine()
            args_string: str = "cls.{1}".format(cls, cls.get_primary_name(cls))
            with Session(dbController.Engine) as session:
                Primary = session.query(func.count(eval(args_string))).scalar()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

        return 0 if not isinstance(Primary, int) else Primary

    @classmethod
    def has_limit(cls, size: int = 1) -> bool:
        if not hasattr(cls, '__tablename__'):
            return False
        dbController.initEngine()
        has_table = dbController.Engine.dialect.has_table(dbController.Engine.connect(), cls.__tablename__)
        if not has_table:
            return False
        Primary = 0
        try:
            dbController.initEngine()
            args_string: str = "cls.{1}".format(cls, cls.get_primary_name(cls))
            with Session(dbController.Engine) as session:
                Primary = session.query(func.count(eval(args_string))).scalar()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

        return isinstance(Primary, int) and Primary >= size

    @classmethod
    def has_empty(cls) -> bool:
        if not hasattr(cls, '__tablename__'):
            return True
        dbController.initEngine()
        has_table = dbController.Engine.dialect.has_table(dbController.Engine.connect(), cls.__tablename__)
        if not has_table:
            return True
        Primary = 0
        try:
            dbController.initEngine()
            args_string: str = "cls.{1}".format(cls, cls.get_primary_name(cls))
            with Session(dbController.Engine) as session:
                Primary = session.query(func.count(eval(args_string))).scalar()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        size = 0 if not isinstance(Primary, int) else Primary
        return size == 0

    @classmethod
    def getMaxPrimary(cls):
        Primary = 1

        try:
            dbController.initEngine()
            args_string: str = "cls.{1}".format(cls, cls.get_primary_name(cls))
            with Session(dbController.Engine) as session:
                Primary = session.query(func.max(eval(args_string))).scalar()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        # MaxPrimary = session.query(func.max()).scalar()
        return Primary

    @classmethod
    def getMinPrimary(cls):
        Primary = 1

        try:
            dbController.initEngine()
            args_string: str = "cls.{1}".format(cls, cls.get_primary_name(cls))
            with Session(dbController.Engine) as session:
                Primary = session.query(func.min(eval(args_string))).scalar()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        # MaxPrimary = session.query(func.max()).scalar()
        return Primary

    @classmethod
    def getMinPrimaryItem(cls):
        Primary = 1
        item: cls = None
        try:
            dbController.initEngine()
            args_string: str = "cls.{1}".format(cls, cls.get_primary_name(cls))
            with Session(dbController.Engine) as session:
                Primary = session.query(func.min(eval(args_string))).scalar()
                item = session.query(cls).filter_by(**{cls.get_primary_name(cls): Primary}).first()
                if item is not None:
                    session.refresh(item)
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        # MaxPrimary = session.query(func.max()).scalar()
        return item

    @classmethod
    def getMaxPrimaryItem(cls):
        Primary = 1
        item: cls = None
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                args_string: str = "cls.{1}".format(cls, cls.get_primary_name(cls))
                Primary = session.query(func.max(eval(args_string))).scalar()
                item = session.query(cls).filter_by(**{cls.get_primary_name(cls): Primary}).first()
                if item is not None:
                    session.refresh(item)
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        # MaxPrimary = session.query(func.max()).scalar()
        return item

    @staticmethod
    def refreshItem(item, session):

        try:
            model_keys: list[str] = item.get_model_fields()
            if len(model_keys) > 0:
                item.initValue()
                for _property in model_keys:
                    _item = getattr(item, _property)
                    if _item is not None:
                        _model_keys: list[str] = _item.get_model_fields()
                        if len(_model_keys) > 0:
                            # _item.initValue()
                            DBInterface.refreshItem(_item, session)
        except Exception as e:
            pass

    @classmethod
    def getItem(cls, Primary: int = 1):
        item: cls = None
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter_by(**{cls.get_primary_name(cls): Primary}).first()
                if item is not None:
                    session.refresh(item)
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        # MaxPrimary = session.query(func.max()).scalar()
        return item
    @classmethod
    def query(cls, *args):
        item = None
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                item = session.query(*args).scalar()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)

        return item
    @classmethod
    def create_table(cls) -> int:
        isWrong: int = RECODE_FAILURE
        try:
            model: cls = cls.__new__(cls)
            model.__init__()
            model.initEngine()
            if not model.has_Engine:
                return isWrong
            with Session(model.Engine) as session:
                model.metadata.create_all(model.Engine, checkfirst=True)
                session.close()
            isWrong = RECODE_SUCCEED
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong

    @classmethod
    def drop_table(cls) -> int:
        isWrong: int = RECODE_FAILURE
        try:
            model: cls = cls.__new__(cls)
            model.__init__()
            model.initEngine()
            if not model.has_Engine:
                return isWrong
            with Session(model.Engine) as session:
                model.metadata.drop_all(model.Engine, checkfirst=False)
                session.close()
            isWrong = RECODE_SUCCEED
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong

    @classmethod
    def filter(cls, *args) -> list:
        isWrong: int = RECODE_FAILURE
        items: list[cls] = []
        dbController.initEngine()
        try:
            with Session(dbController.Engine) as session:
                items = session.query(cls).filter(*args).all()
                item: cls
                for item in items:
                    DBInterface.refreshItem(item, session)
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return items

    @classmethod
    def filter_count(cls, *args) -> int:
        count: int = 0
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                count = session.query(cls).filter(*args).scalar()
                count = 0 if not isinstance(count, (int, float)) else int(count)
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return count

    @classmethod
    def Primary(cls, primary: object):
        item: cls = None
        dbController.initEngine()
        try:
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter_by(**{cls.get_primary_name(cls): primary}).first()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return item
    @classmethod
    def get(cls, *args):

        isWrong: int = RECODE_FAILURE
        item: cls = None
        dbController.initEngine()
        try:
            with Session(dbController.Engine) as session:
                item = session.query(cls).filter(*args).first()
                if item is not None:
                    DBInterface.refreshItem(item, session)
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return item

    @classmethod
    def all(cls) -> list:
        isWrong: int = RECODE_FAILURE
        items: list[cls] = []

        dbController.initEngine()
        try:
            with Session(dbController.Engine) as session:
                items = session.query(cls).all()
                item: cls
                for item in items:
                    DBInterface.refreshItem(item, session)
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return items

    @classmethod
    def append_all(cls, items: list) -> int:
        isWrong: int = RECODE_FAILURE
        item: cls
        items: list[cls]
        models: list[cls]
        is_save: bool = False
        try:

            dbController.initEngine()
            models = [item for item in items if item is not None and type(item) == cls]
            with Session(dbController.Engine) as session:
                if not is_save:
                    try:
                        session.bulk_save_objects(objects=models, return_defaults=True)
                        session.commit()
                        is_save = True
                    except Exception as e:
                        session.rollback()
                        is_save = False
                        AppUtils.print_Exception(e)
                if not is_save:
                    try:

                        session.add_all(models)
                        session.flush(models)
                        session.commit()
                        is_save = True
                    except Exception as e:
                        session.rollback()
                        is_save = False
                        AppUtils.print_Exception(e)


                if not is_save:
                    try:

                        [cls.set_orm_property(item, cls.get_primary_name(item), None) for item in items if item is not None and type(item) == cls]
                        session.bulk_save_objects(models)
                        session.commit()
                        is_save = True
                    except Exception as e:
                        session.rollback()
                        is_save = False
                        AppUtils.print_Exception(e)



                isWrong = RECODE_SUCCEED if is_save else RECODE_FAILURE
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong

    @classmethod
    def remove_all(cls, items: list) -> int:
        isWrong: int = RECODE_FAILURE
        buffer: list[cls] = [item for item in items if isinstance(items, cls)]
        dbController.initEngine()
        try:

            with Session(dbController.Engine) as session:
                try:
                    model_keys: list[str] = cls.get_model_fields()
                    if len(model_keys) > 0:
                        for item in buffer:
                            for _property in model_keys:
                                session.delete(getattr(item, _property))
                        session.delete(item)
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as e:
                    AppUtils.print_Exception(e)
                    session.rollback()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong
    @classmethod
    def model_update(cls, data: dict, *filters):
        isWrong: int = RECODE_FAILURE
        try:
            dbController.initEngine()
            with Session(dbController.Engine) as session:
                try:
                    session.query(cls).filter(*filters).update(data)
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as e:
                    AppUtils.print_Exception(e)
                    session.rollback()
                    try:
                        session.bulk_save_objects(data)
                        session.commit()
                    except Exception as ex:
                        session.rollback()


                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong
    @classmethod
    def clear(cls) -> int:
        isWrong: int = RECODE_FAILURE
        items: list[cls]
        dbController.initEngine()
        try:

            with Session(dbController.Engine) as session:
                try:
                    items = session.query(cls).all()
                    model_keys: list[str] = cls.get_model_fields()

                    for item in items:
                        item.initValue()
                        if len(model_keys) > 0:
                            try:
                                for _property in model_keys:
                                    session.delete(getattr(item, _property))
                            except Exception as e:
                                pass
                        session.delete(item)
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as e:
                    AppUtils.print_Exception(e)
                    session.rollback()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong


    def delete(self) -> int:
        isWrong: int = RECODE_FAILURE
        dbController.initEngine()
        try:

            with Session(dbController.Engine) as session:
                try:
                    model_keys: list[str] = self.get_model_fields()
                    if len(model_keys) > 0:
                        for _property in model_keys:
                            session.delete(getattr(self, _property))
                    session.delete(self)
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as e:
                    AppUtils.print_Exception(e)
                    session.rollback()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong


    def append(self) -> int:
        isWrong: int = RECODE_FAILURE
        dbController.initEngine()
        try:

            with Session(dbController.Engine) as session:
                try:

                    session.add(self)
                    session.flush()
                    session.refresh(self)
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as e:
                    AppUtils.print_Exception(e)
                    session.rollback()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong


    def remove(self, *args) -> int:
        isWrong: int = RECODE_FAILURE
        dbController.initEngine()
        try:

            with Session(dbController.Engine) as session:
                try:
                    model_keys: list[str] = self.get_model_fields()
                    items = session.query(type(self)).filter(*args).all()
                    if len(model_keys) > 0:
                        for item in items:
                            for _property in model_keys:
                                session.delete(getattr(self, _property))
                        session.delete(item)
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as e:
                    AppUtils.print_Exception(e)
                    session.rollback()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong


    def update(self, *args) -> int:
        isWrong: int = RECODE_FAILURE
        dbController.initEngine()
        items: list
        buffer: dict[str, object] = self.to_DICT(self, False)
        try:

            with Session(dbController.Engine) as session:
                try:
                    session.query(type(self)).filter(*args).update(buffer)
                    # model_keys: list[str] = self.get_model_fields()

                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as e:
                    AppUtils.print_Exception(e)
                    session.rollback()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong


    def save(self) -> int:
        isWrong: int = RECODE_FAILURE
        dbController.initEngine()
        items: list
        buffer: dict[str, object] = self.to_DICT(self, False)
        try:
            primary: str = self.get_primary_name(self)


            with Session(dbController.Engine) as session:
                try:
                    if self.get_property(primary) is None:
                        session.add(self)
                    else:
                        session.query(type(self)).filter_by(**{primary: self.get_property(primary)}).update(buffer)
                    session.commit()
                    isWrong = RECODE_SUCCEED
                except Exception as e:
                    AppUtils.print_Exception(e)
                    session.rollback()
                session.close()
        except Exception as e:
            from AppLog.logHelper import logDB
            logDB << AppUtils.toString(e)
        return isWrong

    @property
    def DICT_DATA(self) -> dict[str, object]:
        buffer: dict[str, object]  = {}
        if isinstance(self, DeclarativeBase):
            buffer = DBInterface.to_DICT(self)
        else:
            if not self.has_field or not self.has_types:
                return buffer

            for index, _property in enumerate(self.__field__):
                buffer[_property] = getattr(self, _property, None)


        # fields: list[str] = self.get_model_fields()
        # if len(fields) > 0:
        #     try:
        #         dbController.initEngine()
        #         with Session(dbController.Engine) as session:
        #             item = session.merge(self)
        #             for _property in fields:
        #                 try:
        #                     buffer[_property] = self.to_DICT(getattr(item, _property))
        #                 except Exception as e:
        #                     AppUtils.print_Exception(e)
        #     except Exception as e:
        #         AppUtils.print_Exception(e)
        #         pass
        return buffer




    @property
    def has_field(self) -> bool:
        return hasattr(self, '__field__') and len(self.__field__) > 0

    @property
    def has_types(self) -> bool:
        return hasattr(self, '__types__') and len(self.__types__) > 0

    def hasAttribute(self, name: str, TYPE: type):
        return hasattr(self, name) and isinstance(getattr(self, name, None), TYPE)

