使用装饰器在SQLAlchemy中创建引擎

问题描述 投票:1回答:1

我的MySQL服务器上有几个数据库实例,我想创建一个小库来处理它们。所有DB都具有相同的结构 - 具有相同列的相同表。我使用SQLAlchemy来处理这个DB,但是我不能同时使用一个引擎来建立与多个DB的连接。那么,让我们举一个例子:

+----------+
| Database |
+----------+
| DB1      |
| DB2      |
| DB3      |
| DB4      |
+----------+

所有这些都有结构:

+----------------+
| Tables_in_DB_N |
+----------------+
| table_1        |
| table_2        |
| table_3        |
+----------------+

所以,我有一个想法,使用装饰器来创建引擎和Session类:

Session = None
def decor(func, user=USERNAME, passw=PASSWORD, host=HOSTNAME, port=POST, db=DB):
    def real_decor(func):
        def wrapper(*args, **kwargs):
            engine = create_engine('mysql+mysqlconnector://{user}:{passw}@{host}:{port}/{db}'.format(user=user, passw=passw, host=host, port=port, db=db))
            global Session
            Session = sessionmaker(bind=engine)
            return func(*args, **kwargs)
        return wrapper
    return real_decor

和使用此装饰器示例的函数:

@decor(db='DB1')
def get_db1_table1_values():
    session = Session()
    values = session.query(Table1).all()
    session.close()
    return values

此解决方案有效。我真的不喜欢用global Session破解...所以,还有其他方法可以做这个功能吗?

python sqlalchemy
1个回答
2
投票

这是一个有趣的问题,如果不了解应用程序的生命周期,很难找到适合您用例的解决方案,但这是一次尝试:

def another_decor(user=USERNAME, passw=PASSWORD, host=HOSTNAME, port=PORT, db=DB):
    def real_decor(func):
        def wrapper(*args, **kwargs):
            engine = create_engine('mysql+mysqlconnector://{user}:{passw}@{host}:{port}/{db}'.format(user=user, passw=passw, host=host, port=port, db=db))
            session = sessionmaker(bind=engine)
            return func(session, *args, **kwargs)
        return wrapper
    return real_decor

使用这个装饰器,它会将会话直接注入调用函数,并避免使用global关键字。这样做需要像下面这样定义数据库访问功能:

@another_decor(db='three')
def get_three_table1_values(session):
    session = session()
    query = session.query(Table1).all()
    session.close()
    return query

使用它自己的EngineSession来装饰每个数据库访问函数,这取决于SQLAlchemy如何管理其数据库连接,可能很容易耗尽与数据库的连接。

MySQL通常在内存中运行,基于SQLAlchemys documentation我认为它将汇集连接。所以这种用法可能没问题。

© www.soinside.com 2019 - 2024. All rights reserved.