【问题标题】:Best way to integrate SqlAlchemy into a Django project将 SqlAlchemy 集成到 Django 项目中的最佳方法
【发布时间】:2011-09-30 04:58:25
【问题描述】:

我将我的 Django 应用程序更改为使用 SQLAlchemy,它现在可以工作了。

但我想知道我应该把这些行放在哪里:

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

我问的原因是因为我想在很多地方使用 SQLAlchemy,我认为每次我需要使用数据库时调用这三行代码并不正确/强大/编写良好。

我需要 SA 的地方是:

  • 在我看来,当然
  • 在我写的一些中间件中
  • 在我的模型中。就像在 get_all_tags 中的 BlogPost 模型一样。

我认为正确的是获取会话,如果会话关闭则重新连接到数据库,或者如果存在则返回当前连接的会话。

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

感谢您的帮助!

注意:我已经按照本教程将 SA 实现到我的 Django 应用程序中,但是这篇并没有告诉我将这 3 行放在哪里 (http://lethain.com/entry/2008/jul/23/replacing-django-s-orm-with-sqlalchemy/)。

【问题讨论】:

  • 请原谅我问你为什么一开始就放弃 Django 的模型系统。 (我很想知道为什么。)
  • 搜索startup code 的放置位置,也许这个模块可以帮助你:sqlahelper
  • 如果您的模型需要访问会话,那么您的模型错误,会话与模型处于不同的抽象层
  • @Chris Morgan:使用 sqlalchemy 不需要切换整个框架。 Django 只是松散地与它的 orm 耦合。 Sqlalchemy 比 django 的 orm 强大一点,但 django 的其他一些部分与原生 orm 很好地集成,因此如果不了解具体应用程序,很难说这是否是一个不错的选择。
  • 我刚刚找到了django-sqlalchemy 项目。我不知道它是否适合您的需求,但绝对值得一读。

标签: python django sqlalchemy


【解决方案1】:

前两个engineSession可以放在settings.py;毕竟,它们是配置。

实际上创建会话需要稍微小心一点,因为session 本质上是一个“事务”。最简单的做法是在需要时在每个视图函数中创建它,并在返回之前提交它们。如果你想要更多的魔法,或者如果你想/需要在视图函数之外使用会话,你应该定义一些middleware,比如

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

【讨论】:

  • 不错的一个。但我有两个问题:我的代码只会读取(选择)数据库。那我必须承诺吗?在每个请求中创建一个新会话是否会打开一个新的数据库连接?还是会适应(如果不存在则打开与数据库的新连接,如果存在则重新使用)?因为如果每个请求都创建一个新的数据库连接,我会担心负载很重。感谢您的帮助和回复。
  • 连接池由sqlalchemy.create_engine的参数控制。感兴趣的参数是poolclass,它的默认值为QueuePool,它将创建和重用最多5个(默认情况下)连接。如果您不想要或不需要自动提交行为,那么您可以更改配方,可能消除process_response,或者在请求(或响应)上设置一个标志以指示是否需要提交。为了最大程度地控制资源的使用方式,只需在需要会话时致电Session()
  • 如果我理解正确,这意味着如果我调用 6 次 Session(),它只会打开 5 个到数据库的连接,然后重用其中一个? (第六个)
  • 如果会话在创建下一个会话之前被垃圾收集,它可能只打开一个连接。但你的理解是正确的。您可以创建数千个会话,但最多将打开 5 个连接到数据库(或您选择的任何值)
猜你喜欢
  • 1970-01-01
  • 2015-02-21
  • 2020-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2017-11-04
  • 2020-04-04
相关资源
最近更新 更多