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

时间:2016-03-18 16:54:24

标签: python sqlalchemy

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

"""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模块期间从全局范围内未知的配置创建。

我所看到的是在我的应用程序" main"中设置所有内容。 (或在线程的主要功能中),然后假设会话在其他地方配置(例如上面的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'])

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

3 个答案:

答案 0 :(得分:1)

这很老了,我从未接受过以下任何答案,但由于@univerio的评论以及在SQLAlchemy中多个项目中连续使用了3年以上,我现在选择的方法是继续完全按照我在操作:

  1. 创建一个myapp.db模块,该模块定义Session = ScopedSession(sessionmaker())
  2. 在需要的任何地方导入from myapp.db import Session
  3. 在我的应用的main或相关的初始化代码中,执行以下操作:
def main(): 
     config = load_config_from_file()
     engine = create_engine(**config['db'])
     Session.configure(bind=engine)

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

我已经在Web应用程序,命令行工具和长期运行的后端流程中成功使用了这种模式,到目前为止,无需更改它。 Ot非常简单,可重用并且效果很好,我建议所有在这里绊脚的人都推荐它,因为他们问自己和我三年前一样。

答案 1 :(得分: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))

答案 2 :(得分:0)

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