跨模块共享数据库连接

时间:2019-09-04 14:56:38

标签: python design-patterns pyodbc

我正在尝试从代码中的多个位置访问pyodbc连接。

当前,用户通过命令行传递连接详细信息,而我使用plac.annotation处理它们,问题是,我不知道如何在所有项目中共享该对象。到目前为止,我有:

用于存储连接的Singleton类

class DatabaseInstance:
    """
    Singleton Class holding a Database Connection
    """

    class __DatabaseInstance:
        def __init__(self, server, database, schema, table, user, password):
            self.server = server
            self.database = database
            self.schema = schema
            self.table = table
            self.username = user
            self.passw = password

        def __str__(self):
            return "{} DB: {}@[{}].[{}].[{}] @ {}".format(
                repr(self),
                self.server,
                self.database,
                self.schema,
                self.table,
                self.username,
            )

        def get_connection(self):
            """
            TODO
            """
            if DatabaseInstance.connection:
                return DatabaseInstance.connection
            else:
                DatabaseInstance.connection = pyodbc.connect(
                    "DRIVER=SQL Server;SERVER="
                    + self.server
                    + ";PORT=1433;DATABASE="
                    + self.database
                    + ";UID="
                    + self.username
                    + ";PWD="
                    + self.passw
                )
                return DatabaseInstance.connection

    instance = None
    connection = None

    def __init__(self, server, database, schema, table, user, password):
        if not DatabaseInstance.instance:
            DatabaseInstance.instance = DatabaseInstance.__DatabaseInstance(
                server, database, schema, table, user, password
            )

    def __getattr__(self, name):
        return getattr(self.instance, name)

现在,我主要是获取参数,并为数据库创建一个实例:

connection = DatabaseInstance(
    server=server,
    database=database,
    schema=schema,
    table=table,
    user=user,
    password=passw,
)

应用程序需要从不同的模块和子模块访问此对象,但是connection具有功能的范围。

除了将对象从一个函数向下传递到另一个函数,直到被必要的函数使用为止,还有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

不要在主实例中实例化单例。以db实例化模块中的DatabaseInstance,然后在需要访问单例时,进入模块并使用它。

import .thatmodule
db = thatmodule.db.get_connection()

最好实例化您的主体并将其传递到需要访问数据库的代码中,以回答您的最后一个问题。不过,它使API更加难看。

两个都很好。选择取决于您。