簡體   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