在Django项目中集成SqlAlchemy的最佳方式

20 投票
1 回答
15113 浏览
提问于 2025-04-16 21:00

我把我的Django应用改成用SQLAlchemy了,现在可以正常工作了。

不过我在想,这几行代码应该放在哪里:

engine = sqlalchemy.create_engine(settings.DATABASE_URL)
Session = sqlalchemy.orm.sessionmaker(bind=engine)
session = Session()

我之所以问这个,是因为我想在很多地方使用SQLAlchemy,我觉得每次需要用到数据库的时候都调用这三行代码不太合适,也不够强大或者写得不够好。

我需要用到SQLAlchemy的地方有:

  • 当然是在我的视图里
  • 在我写的一些中间件里
  • 在我的模型里,比如在get_all_tags这个博客文章模型里。

我觉得正确的做法是,如果会话关闭了就重新连接数据库获取会话,如果会话已经存在且连接着,就直接返回当前的会话。

我该如何在我的Django应用中正确使用SQLAlchemy呢?

谢谢你的帮助!

备注:我已经按照这个教程把SQLAlchemy集成到我的Django应用里,但这个教程没有告诉我具体应该把那三行代码放在哪里(http://lethain.com/entry/2008/jul/23/replacing-django-s-orm-with-sqlalchemy/)。

1 个回答

27

对于前面提到的两个东西,engineSession,你可以把它们放在 settings.py 文件里,因为它们都是配置内容。

实际上,创建一个会话(session)需要稍微多一点注意,因为会话本质上就是一个“交易”。最简单的方法是在每个视图函数中根据需要创建会话,并在返回之前提交它们。如果你想要一些更高级的功能,或者需要在视图函数外使用会话,那么你应该定义一些中间件,像这样:

class MySQLAlchemySessionMiddleware(object):
    def process_request(self, request):
        request.db_session = settings.Session()

    def process_response(self, request, response):
        try:
            session = request.db_session
        except AttributeError:
            return response
        try:
            session.commit()
            return response
        except:
            session.rollback()
            raise

    def process_exception(self, request, exception):
        try:
            session = request.db_session
        except AttributeError:
            return
        session.rollback()

这样,每个视图在请求中都会有一个 db_session 属性,视图可以根据需要使用它,所有添加的内容会在响应完成时被提交。

别忘了把这个中间件添加到 MIDDLEWARE_CLASSES 中哦。

撰写回答