无法跨Python中的多个对象使用相同的SQLite连接

2024-10-05 13:23:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用wxPython和SQLite开发一个Python桌面应用程序。SQLite db基本上被用作我的程序的保存文件,因此我可以保存、备份和重新加载输入的数据。我已经为UI的各个部分创建了单独的类,以便更容易从“主”窗口进行管理。我遇到的问题是,每个控件都需要访问数据库,但是文件名以及连接名需要是动态的。我最初创建了一个DBManager类,该类使用连接字符串硬编码了一个类变量,它可以工作,但不允许我更改文件名。比如说

class DBManager:
    conn = sqlite3.Connection('my_file.db')

#This could then be passed to other objects as needed

class Control1:
    file = DBManager()

class Control2:
    file = DBManager()

etc.

但是,我在尝试使用动态文件名创建此对象时遇到了很多问题,同时在所有控件中使用相同的连接。我试过的一些例子

class DBManager:
    conn = None

    def __init__(self):
        pass

    def __init__(self, filename):
        self.conn = sqlite3.Connection(filename)

class Control1:
    file = DBManager()

class Control2:
    file = DBManager()

上述方法不起作用,因为Python不允许重载构造函数,所以我总是要传递一个文件名。我尝试向构造函数添加一些代码,以便根据传递的文件名是否为空而采取不同的操作

class DBManager:
    conn = None

    def __init__(self, filename):
        if filename != '':
            self.conn = sqlite3.Connection(filename)

class Control1:
    file = DBManager('')

class Control2:
    file = DBManager('')

这让我可以编译,但控件只有一个空连接。conn对象是None。在类变量被创建之后,我似乎无法更改它?还是我只是做错了什么

我曾经考虑过创建一个DBManager实例,然后将其传递到每个控件中,但是如果在启动程序后需要加载一个新的DB,那将是一个巨大的混乱。而且,它也不那么优雅

因此,我正在寻找实现带有动态文件名的单连接路径的想法。值得一提的是,这完全是为了个人使用,所以它实际上不必遵循“良好”的编码约定


Tags: selfnone文件名def动态connectionfilenameconn
1条回答
网友
1楼 · 发布于 2024-10-05 13:23:08

最后一个例子的解释

在上一个示例中,您得到了None,因为您在Control1和Control2中使用空字符串作为输入实例化DBManager,并且DBManager构造函数有一个if语句,表示如果filename只是一个空字符串,则不应创建连接。这导致self.conn实例变量从未设置,对conn的任何引用都将解析为conn类变量,该类变量实际上设置为None

self.conn将创建仅可由特定对象访问的实例变量。 DBManager.conn将引用类变量,这是您要更新的

示例解

如果您只想保持一个连接,则需要使用例如a。类变量,并在每次与新数据库交互时更新该类变量

import sqlite3
from sqlite3 import Connection


class DBManager:
    conn = None

    def __init__(self, filename):
        if filename != '':
            self.filename = filename

    def load(self) -> Connection:
        DBManager.conn = sqlite3.Connection(self.filename) # updating class variable with new connection
        print(DBManager.conn, f" used for {self.filename}")
        return DBManager.conn


class Control1:
    db_manager = DBManager('control1.db')
    conn = db_manager.load()


class Control2:
    db_manager = DBManager('control2.db')
    conn = db_manager.load()


if __name__ == "__main__":
    control1 = Control1()
    control2 = Control2()

将输出以下内容。请注意,类变量conn在实例化每个控件时引用了不同的内存地址,表明它已更新

<sqlite3.Connection object at 0x10dc1e1f0>  used for control1.db
<sqlite3.Connection object at 0x10dc1e2d0>  used for control2.db

相关问题 更多 >

    热门问题