SQLAlchemy最佳实践:何时/如何配置scoped_session?

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

我试图找出正确的方法来使用SQLAlchemy范围会话“正确的方式”,同时保持定义会话的逻辑与配置分开并与使用会话分开。有人告诉我,有一个很好的方法是建立一个全球scoped_session工厂,我可以随处使用:

"""myapp/db.py
"""

from sqlalchemy.orm import sessionmaker, scoped_session

Session = scoped_session(sessionmaker())

然后,当我想使用它时:

"""myapp/service/dosomething.py
"""

from myapp.db import Session

def do_something(data): 
    """Do something with data
    """
    session = Session()
    bars = session.query(Bar).all()
    for bar in bars:
        bar.data = data
    session.commit()

这似乎是正确的,但我的问题是,在我看到的所有示例中,sessionmaker还会设置会话的一些参数,即最重要的是绑定引擎。这对我来说毫无意义,因为实际的数据库引擎将在导入myapp.db模块期间从全局范围内未知的配置创建。

我所看到的是在我的应用程序的“主”(或线程的主函数)中设置所有内容,然后假设会话在其他地方配置(例如上面的do_something()使用时):

"""myapp/main.py
"""

from sqlalchemy import create_engine
from myapp.db import Session
from myapp.service.dosomething import do_something

def main(): 
    config = load_config_from_file()
    engine = create_engine(**config['db'])
    Session.configure(bind=engine)

    do_something(['foo', 'bar'])

这看起来像是一种正确的方法吗?我没有找到任何这种流程的好例子,但我发现的大多数其他例子似乎都过于简化或特定于框架。

python sqlalchemy
2个回答
0
投票

你可以做的是将配置分成一个单独的模块:

"""myapp/cfg.py
"""
config = load_config_from_file()

然后您可以在任何需要的地方导入此文件,包括在db模块中,这样您就可以构建引擎以及会话:

"""myapp/db.py
"""
from .cfg import config
engine = create_engine(**config['db'])
Session = scoped_session(sessionmaker(bind=engine))

0
投票

想想单身人士。在你的情况下from myapp.db import Session,Session是单身和全球的。只需在应用程序的开头配置Session即可。您应该有一个配置过程,如从文件或env加载配置数据,在所有配置准备就绪后,运行真实程序。

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