使用字典开关从 init 返回 sqlalchemy 引擎对象的方法

way of returning sqlalchemy engine object from init using dictionary switch

刚刚创建了一个帮助程序 class,用于根据用户使用的供应商实例化 Sqlalchemy Engine 对象。

当我的助手 class 的对象被删除时,有什么方法可以 return 引擎对象。

class SqlalchemyEngineInitializer:
    def __init__(self,vendor):
        self.vendor = vendor
        self.engine_pool = {
                                        "sqlite": self.sqlite_engine_init,
                                        "postgres": self.postgres_engine_init,
                                        "mysql": self.mysql_engine_init,
                                        "oracle": self.oracle_engine_init}

        self.engine_pool.get(vendor) #how can this be returned

    def postgres_engine_init(self,user:str,password:str,database:str,hostname:str='localhost'):
        "RETURNS POSTGRES SQLALCHEMY ENGINE OBJECT "
        return create_engine(f'postgresql+psycopg2://{user}:{password}@{hostname}/{database}')

    def sqlite_engine_init(self,user:str,password:str,database:str,hostname:str='localhost'):
        "RETURNS SQLITE SQLALCHEMY ENGINE OBJECT "
        return create_engine(f'postgresql+psycopg2://{user}:{password}@{hostname}/{database}')

init 不允许 return 正在尝试使用 new,但如果不创建实例,是否可以从中 return 是一种很好的做法。

提前感谢您抽出时间!

init() 方法只能return class 的一个实例。在 class 成员中放置引擎后,您可以添加 属性 return 引擎。

如果想模拟switch语句,可以写一个辅助函数:

def switch(v): yield lambda *c: v in c

并将其与 for 循环一起使用:

class SqlalchemyEngineInitializer:
    def __init__(self,vendor):
        self.vendor  = vendor
        self._engine = None

    @property
    def engine(self):
        if self._engine: return self._engine
        for case in switch(self.vendor):
            if case("sqlite"):
               self._engine = create_engine(f'postgresql+psycopg2://{user}:{password}@{hostname}/{database}')
               break
            if case("postgres"):
               self._engine = create_engine(f'postgresql+psycopg2://{user}:{password}@{hostname}/{database}')
               break
            if case("mysql"):
               ...
               break
            if case("oracle"):
               ...
               break
        return self._engine

用法:

dbEngine = SqlalchemyEngineInitializer('mysql').engine

db = SqlalchemyEngineInitializer('mysql')

...

... db.engine ...

如果创建引擎是您的助手 class 所做的唯一事情,那么您应该将其设为一个函数:

def SqlalchemyEngineInitializer(vendor):
    for case in switch(vendor):
       if case("sqlite"):
           return create_engine(f'postgresql+psycopg2://{user}:{password}@{hostname}/{database}')
       if case("postgres"):
           return create_engine(f'postgresql+psycopg2://{user}:{password}@{hostname}/{database}')
       if case("mysql"):
           return ...
       if case("oracle"):
           return ...

用法:

dbEngine = SqlalchemyEngineInitializer('mysql')