【发布时间】:2016-11-10 10:40:45
【问题描述】:
我的问题是在整个应用程序中维护单个数据库连接的最佳方式是什么? 使用单例模式?怎么样?
需要注意的条件:
- 如果有多个请求,我应该使用同一个连接
- 如果连接关闭,请创建一个新连接
- 如果连接超时,我的代码应根据新请求创建新连接。
Django ORM 不支持我的数据库的驱动程序。由于同样的驱动相关问题,我使用pyodbc 连接到数据库。现在我有下面的类来创建和管理数据库连接:
class DBConnection(object):
def __init__(self, driver, serve,
database, user, password):
self.driver = driver
self.server = server
self.database = database
self.user = user
self.password = password
def __enter__(self):
self.dbconn = pyodbc.connect("DRIVER={};".format(self.driver) +\
"SERVER={};".format(self.server) +\
"DATABASE={};".format(self.database) +\
"UID={};".format(self.user) +\
"PWD={};".format(self.password) + \
"CHARSET=UTF8",
# "",
ansi=True)
return self.dbconn
def __exit__(self, exc_type, exc_val, exc_tb):
self.dbconn.close()
但是这种方法的问题是它会为每个查询创建新的数据库连接。遵循单例模式的更好方法是什么?如果连接关闭,我能想到的方式将保留对连接的引用。比如:
def get_database_connection():
conn = DBConnection.connection
if not conn:
conn = DBConnection.connection = DBConnection.create_connection()
return conn
实现这一目标的最佳方法是什么?有什么建议/想法/例子吗?
PS:我正在检查是否使用weakref,它允许创建对对象的弱引用。我认为使用weakref 和单例模式来存储连接变量是个好主意。这样,当 DB 不使用时,我就不必保持连接 alive。你们对此有何看法?
【问题讨论】:
-
pyocdb的第三方后端好像有几个,比如django-pyocdb。为什么不使用其中之一?
-
我使用 IBM Netezza 作为 django-pyodbc 不支持的数据库
-
您可以实现一个仅支持创建连接和游标的最小数据库后端。这样你就可以使用 Django 的连接管理来处理你的连接。我想这比自己实现连接处理要容易。
-
我用工具查看了
django.db.backends.mysql。有 6 个文件,分别是 base.py、client.py、compiler.py、creation.py、introspection.py 和 validation.py。我认为实施起来会有很多开销。可能是我没有完全理解最小数据库后端的定义。在我看来,我正在考虑创建一个 Singleton 类来维护单一连接(已经这样做了),但你的想法对我来说看起来更好。你知道图书馆或博客可以让我了解 Django 的后端是如何工作的吗? -
大部分都与 ORM 有关。我认为如果您在
base.py中实现DatabaseWrapper类,并为其他类使用虚拟类,您可以使用连接和游标来执行原始查询,并依赖Django 的连接管理。恐怕我不知道任何指南或什么的,我自己也只知道一点。
标签: python django singleton database-connection pyodbc