4

寻找人们用来包装 PyODBC 的类模式示例,我在 SO: single database connection through the python application找到了这个示例。

我不明白 DBConnection 类在原始示例中是如何工作的。如果--如何初始化 DBConnector

cls.connection = DBConnector().create_connection()

--没有将所需的初始化值传递给DBConnector()?当我尝试添加它们时,我得到TypeError: DBConnection() takes no arguments

import pyodbc    
class DBConnector(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):
            cls.instance = super(DBConnector, cls).__new__(cls)
        return cls.instance

    def __init__(self, ipaddress, port, dsn, remotedsn):
        self.ipaddress = ipaddress
        self.port = port
        self.dsn = dsn
        self.remotedsn = remotedsn
        self.dsnstr_default = 'OpenMode=F;OLE DB Services=-2;'
        self.dbconn = None

    # creates new connection
    def create_connection(self):
        return pyodbc.connect(self.dsnstr_default,
                                IPAddress = self.ipaddress,
                                Port = self.port,
                                DSN = self.dsn,
                                RemoteDSN = self.remotedsn,
                                autocommit=True)

    # For explicitly opening database connection
    def __enter__(self):
        self.dbconn = self.create_connection()
        return self.dbconn

    def __exit__(self):
        self.dbconn.close()

class DBConnection(object):
    connection = None

    @classmethod
    def get_connection(cls, new=False, *args, **kwargs): << ADDED THIS
        if new or not cls.connection:
            cls.connection = DBConnector(*args, **kwargs).create_connection()
                            /\/\/\/\/\/\/\/\/\/SEE NOTE 
        return cls.connection

    @classmethod
    def GetCompanyInfo(cls):
        """execute query on singleton db connection"""
        connection = cls.get_connection()
        try:
            connection.setencoding('utf-8')
            cursor = connection.cursor()
        except pyodbc.ProgrammingError:
            connection = cls.get_connection(new=True)
            cursor = connection.cursor()
        # Start Query
        cursor.execute("SELECT CompanyName, EIN, SSN FROM Company")
        for cname, ein, ssn in cursor.fetchall():
            result = (cname, ein, ssn)
        # End Query
        cursor.close()
        return result

做了一些功课...

我可以找到几个解释Singleton 模式的示例,因此我可以使用 Connector 类:

a = DBConnector('127.0.0.1', '4500', 'pyauto_local', None)
a.create_connection()
# <pyodbc.Connection at 0x5772110>
a = DBConnector('127.0.0.1', '4500', 'pyauto_local', None)
a.__enter__()
# <pyodbc.Connection at 0x605f278>
a.__exit__()

我做了一些测试...

我有一个成功的测试,手动将连接参数插入到 get_connection 方法中:

cls.connection = DBConnector('127.0.0.1', '4500', 'pyauto_local', None).create_connection()
                             /\/\/\/\/\/\/ NOTED ABOVE
# Testing
cx = DBConnection()
cx.GetCompanyInfo()
# ('Zep', '12-3456789', None)

现在我很好奇

如果我把连接和查询都放在一个类——Monster 类中,我就可以完成。

或者我更了解 Car > Blue Car OOP 模式,在 SO 的另一篇文章中是扩展 Singleton 类的示例。这对我来说更有意义。

现在我真的很好奇原件应该如何工作:

@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

如何在没有 INIT 的情况下将参数放入 DBConnection 类?该帖子还带有 Django 标记,因此他们可能跳过了假定的 Django 上下文?或者 Django 以某种方式免费提供它?

4

0 回答 0