17

我们有一个包含 20 多个模块的 Python 应用程序,其中大部分由多个 Web 和控制台应用程序共享。

我从来没有清楚地了解在多模块 Python 应用程序中建立和管理数据库连接的最佳实践。考虑这个例子:

我有一个为用户定义对象类的模块。它有许多用于在数据库中创建/删除/更新用户的定义。users.py 模块被导入到 a) 基于控制台的实用程序,2) 基于 web.py 的 Web 应用程序和 3) 持续运行的守护进程。

这三个应用程序中的每一个都有不同的生命周期。守护进程可以打开连接并保持打开状态。控制台实用程序连接,确实工作,然后死亡。当然,http 请求是原子的,但是 web 服务器是一个守护进程。

我目前正在打开,使用然后关闭用户类中每个函数内的连接。这似乎是最低效的,但它适用于所有示例。另一种用作测试的方法是声明并打开整个模块的全局连接。另一种选择是在顶层应用程序层创建连接并在实例化类时传递引用,但这对我来说似乎是最糟糕的主意。

我知道每个应用程序架构都是不同的。我只是想知道是否有最佳实践,它会是什么?

4

2 回答 2

16

最好的方法是当你需要做一些操作(比如获取和/或更新数据)时打开连接;操纵数据;在一个查询中将其写回数据库(对性能非常重要),然后关闭连接。打开连接是一个相当轻松的过程。

一些性能缺陷包括

  • 当您肯定不会与之交互时打开数据库
  • 使用比您需要的数据更多的选择器(例如,获取有关所有用户的数据并在 Python 中对其进行过滤,而不是要求 MySQL 过滤掉无用的数据)
  • 写入未更改的值(例如,更新用户配置文件的所有值,仅当他们的电子邮件发生更改时)
  • 让每个字段单独更新服务器(例如,打开数据库,更新用户电子邮件,关闭数据库,打开数据库,更新用户密码,关闭数据库,打开...你明白了)

最重要的是,打开数据库的次数并不重要,重要的是运行了多少次查询。如果您可以让您的代码加入相关查询,那么您就赢得了这场战斗。

于 2013-02-14T20:37:55.537 回答
4

MySQL 连接相对较快,所以这可能不是问题(即您应该测量)。大多数其他数据库需要更多的资源来创建连接。

在需要时创建新连接始终是最安全的,也是不错的首选。一些数据库库,例如 SqlAlchemy,有内置的连接池,它将透明地为您正确地重用连接。

如果您决定要保持连接处于活动状态以便可以重复使用它,则需要注意以下几点:

  1. 仅用于读取的连接比用于修改数据库数据的连接更易于重用。

  2. 当您在连接上启动事务时,请注意在您使用该连接时,没有其他东西可以将该连接用于其他用途。

  3. 长时间存在的连接会变得陈旧并且可以从您下方关闭,因此如果您正在重新使用连接,您需要检查它是否仍然“活动”,例如通过发送“select 1”和验证您是否得到结果。

我个人建议不要实现自己的连接池算法。当出现问题时,很难调试。而是选择一个为您完成它的数据库库。

于 2013-02-14T20:45:38.660 回答