Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
整个python应用程序中的单个数据库连接(遵循单例模式)_Python_Django_Singleton_Database Connection_Pyodbc - Fatal编程技术网

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

整个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

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

需要注意的条件:

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

  • 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.