简体   繁体   English

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

[英]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:需要照顾的条件:

  1. In case of multiple requests, I should be using the same connection如果有多个请求,我应该使用相同的连接
  2. In case connection is closed, create a new connection如果连接关闭,创建一个新连接
  3. If the connection has timed-out, on new request my code should create a new connection.如果连接超时,我的代码应该根据新请求创建一个新连接。

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.

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