整个python应用程序中的单个数据库连接(遵循单例模式)
我的问题是,在整个应用程序中维护单个数据库连接的最佳方式是什么?使用Singleton模式?怎么做 需要注意的条件:整个python应用程序中的单个数据库连接(遵循单例模式),python,django,singleton,database-connection,pyodbc,Python,Django,Singleton,Database Connection,Pyodbc,我的问题是,在整个应用程序中维护单个数据库连接的最佳方式是什么?使用Singleton模式?怎么做 需要注意的条件: 如果有多个请求,我应该使用相同的连接 如果连接已关闭,请创建一个新连接 如果连接超时,根据新请求,我的代码应该创建一个新连接 Django ORM不支持数据库驱动程序。由于相同的驱动程序相关问题,我使用pyodbc连接到数据库。目前,我正在学习以下创建和管理DB连接的课程: class DBConnection(object): def __init__(self, d
Django ORM不支持数据库驱动程序。由于相同的驱动程序相关问题,我使用
pyodbc
连接到数据库。目前,我正在学习以下创建和管理DB连接的课程:
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
和单例模式来存储连接变量。这样,当DB不使用时,我就不必让连接保持活动状态。你们对此有何看法?现在,我将继续使用单例类方法。任何看到这一点的潜在缺陷的人,都可以提一提:)
DBConnector
class用于创建连接
class DBConnector(object):
def __init__(self, driver, server, database, user, password):
self.driver = driver
self.server = server
self.database = database
self.user = user
self.password = password
self.dbconn = None
# creats new connection
def create_connection(self):
return 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)
# For explicitly opening database connection
def __enter__(self):
self.dbconn = self.create_connection()
return self.dbconn
def __exit__(self, exc_type, exc_val, exc_tb):
self.dbconn.close()
DBConnection
class用于管理连接
class DBConnection(object):
connection = None
@classmethod
def get_connection(cls, new=False):
"""Creates return new Singleton database connection"""
if new or not cls.connection:
cls.connection = DBConnector().create_connection()
return cls.connection
@classmethod
def execute_query(cls, query):
"""execute query on singleton db connection"""
connection = cls.get_connection()
try:
cursor = connection.cursor()
except pyodbc.ProgrammingError:
connection = cls.get_connection(new=True) # Create new connection
cursor = connection.cursor()
cursor.execute(query)
result = cursor.fetchall()
cursor.close()
return result
类DBConnector(对象):
定义新的(cls):
如果不是hasattr(cls,“实例”):
cls.instance=super(DBConnector,cls)。\uuuu新建\uuuuuu(cls)
返回cls.instance
定义初始化(自):
#构造函数中的数据库连接代码
con=DBConnector()
con1=DBConnector()
con为con1#输出为真
希望,以上代码将有所帮助。
pyocdb似乎有一些第三方后端,例如。为什么不使用其中一个呢?我使用IBM Netezza作为django pyodbcYou不支持的数据库。您可以实现一个只支持创建连接和游标的最小数据库后端。这样,您就可以使用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的连接管理。恐怕我不知道任何指南或其他东西,我自己也只知道一点。您应该确保线程之间不共享连接,否则您可能会遇到一些令人惊讶且难以调试的行为。您可以将连接保存在threading.local()
对象上,这样每个线程都有自己的单例连接。@knbk:我只是在共享连接对象,但在执行查询函数中为每个查询创建一个新的本地光标。因此,由于查询/结果关系是由游标维护的,所以即使异步调用execute\u query
,我也看不到任何危害。这也是我的假设。或者我错了?“threadsafety是整数1,表示线程可以共享模块,但不能共享连接。请注意,连接和游标可能由不同的线程使用,只是不能同时使用。”--因此,不能在尝试同时访问数据库的线程之间共享连接。注意,如果不将*args、**kwargs
传递到\uuuu new\uuuu
,我将无法获得任何结果。
class DBConnector(object):
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super(DBConnector, cls).__new__(cls)
return cls.instance
def __init__(self):
#your db connection code in constructor
con = DBConnector()
con1 = DBConnector()
con is con1 # output is True
Hope, above code will helpful.