[英]single database connection throughout the python application (following singleton pattern)
My Question is what is the best way to maintain the single database connection in the entire application?我的问题是在整个应用程序中维护单个数据库连接的最佳方法是什么? Using Singleton Pattern?使用 Singleton 模式? How?如何?
Conditions that are needed to be taken care of:需要照顾的条件:
The driver to my Database is not supported by the Django ORM. And due to same driver related issues, I am using pyodbc
to connect to the database. Django ORM 不支持我的数据库的驱动程序。并且由于与驱动程序相关的相同问题,我正在使用pyodbc
连接到数据库。 Right now I am having below class for creating and managing the DB connections:现在我有以下 class 用于创建和管理数据库连接:
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()
But the issue with this approach is that it will create new database connection for each query.但是这种方法的问题是它会为每个查询创建新的数据库连接。 What will be the better way to do it following singleton pattern ?遵循singleton 模式的更好方法是什么? The way I can think of will hold the reference to the connection if the connection is closed.如果连接关闭,我能想到的方式将保留对连接的引用。 Something like:就像是:
def get_database_connection():
conn = DBConnection.connection
if not conn:
conn = DBConnection.connection = DBConnection.create_connection()
return conn
What will be the best way to achieve this?实现这一目标的最佳方式是什么? Any suggestion/ideas/examples?有什么建议/想法/例子吗?
PS: I was checking about using weakref
which allows to create weak references to objects. PS:我正在检查使用weakref
允许创建对对象的弱引用。 I think it will be good idea to use weakref
along with singleton pattern for storing the connection variable.我认为将weakref
与 singleton 模式一起用于存储连接变量是个好主意。 This way I won't have to keep the connection alive
when DB is not in use.这样我就不必在不使用数据库时alive
连接。 What you guys say about this?大家对此怎么说?
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.希望,上面的代码会有所帮助。
For now, I am going ahead with the singleton class approach. 目前,我正在采用单例类方法。 Anyone seeing the potential flaws in this, feel to mention them :) 任何人都看到了这个潜在的缺陷,感觉提到他们:)
DBConnector
class for creating a connection 用于创建连接的DBConnector
类
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 for managing the connections 用于管理连接的DBConnection
类
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.