繁体   English   中英

整个 python 应用程序中的单个数据库连接(遵循 singleton 模式)

[英]single database connection throughout the python application (following singleton pattern)

我的问题是在整个应用程序中维护单个数据库连接的最佳方法是什么? 使用 Singleton 模式? 如何?

需要照顾的条件:

  1. 如果有多个请求,我应该使用相同的连接
  2. 如果连接关闭,创建一个新连接
  3. 如果连接超时,我的代码应该根据新请求创建一个新连接。

Django ORM 不支持我的数据库的驱动程序。并且由于与驱动程序相关的相同问题,我正在使用pyodbc连接到数据库。 现在我有以下 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()

但是这种方法的问题是它会为每个查询创建新的数据库连接。 遵循singleton 模式的更好方法是什么? 如果连接关闭,我能想到的方式将保留对连接的引用。 就像是:

 def get_database_connection():
     conn = DBConnection.connection
     if not conn:
          conn = DBConnection.connection = DBConnection.create_connection()
     return conn

实现这一目标的最佳方式是什么? 有什么建议/想法/例子吗?

PS:我正在检查使用weakref允许创建对对象的弱引用。 我认为将weakref与 singleton 模式一起用于存储连接变量是个好主意。 这样我就不必在不使用数据库时alive连接。 大家对此怎么说?


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

希望,上面的代码会有所帮助。

目前,我正在采用单例类方法。 任何人都看到了这个潜在的缺陷,感觉提到他们:)

用于创建连接的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 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM