如何确保使用PyQt5.QtSql 关闭数据库连接?
我写了一个应用程序,但总是出现这样的提示:
QSqlDatabasePrivate::removeDatabase: 连接 'qt_sql_default_connection' 仍在使用中,所有查询将停止工作。
我发现通过在执行时提供一个“连接名称”可以解决这个问题:
self.db_connection = QSqlDatabase.addDatabase("QSQLITE", self.db_connection_name)
我想确保我的所有数据库连接都能正确关闭,所以我使用了一个叫做 DatabaseConnectionMaker 的类,并结合 with
块来实现。
在下面的代码中,我已经这样做了,但现在我在一个小的可行性应用程序中不断收到以下输出,以确认 with
块的成功使用:
Table already exists and does not need to be created by dbConnection1.
QSqlDatabasePrivate::removeDatabase: connection 'dbConnection1' is still in use, all queries will cease to work.
Data inserted successfully by dbConnection1
Database connection dbConnection1 closed!!!
Process finished with exit code 0
我就是搞不清楚我哪里出错了。无论我尝试什么,QSqlDatabasePrivate::removeDatabase: 连接 'dbConnection1' 仍在使用中,所有查询将停止工作。
这个提示总是会出现。有人能帮我解答一下吗?
这是我的应用程序:
import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery
from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QMainWindow, QApplication,
QWidget
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.db_name_main = "example.db"
self.setGeometry(100, 100, 570, 600)
self.setWindowTitle("Database Manipulation")
# Create buttons
create_database_button = QPushButton("Create Database ", self)
create_database_button.clicked.connect(self.test_database_creation)
central_widget = QWidget()
layout = QVBoxLayout(central_widget)
layout.addWidget(create_database_button)
self.setCentralWidget(central_widget)
def test_database_creation(self):
with DatabaseConnectionMaker(self.db_name_main, "dbConnection1") as db_connection1:
db_connection1.create_table("""CREATE TABLE IF NOT EXISTS example_table (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER)""")
db_connection1.insert_data("INSERT INTO example_table (name, age) "
"VALUES (?, ?), (?, ?), (?, ?), (?, ?)",
["John", 30, "Alice", 25, "Bob", 35, "Eve", 28])
class DatabaseConnectionMaker:
def __init__(self, db_name, db_connection_name):
self.db_name = db_name
self.db_connection = None
self.db_connection_name = db_connection_name
def connect(self):
self.db_connection = QSqlDatabase.addDatabase("QSQLITE", self.db_connection_name)
self.db_connection.setDatabaseName(self.db_name)
if not self.db_connection.open():
print("Failed to connect to database:", self.db_connection.lastError().text())
return False
return True
def create_table(self, create_table_sql):
query = QSqlQuery(self.db_connection)
# Check if the table already exists
if not self.table_exists():
# If the table does not exist, execute the create_table_sql
# query = QSqlQuery(self.db_connection)
if not query.exec_(create_table_sql):
print("Error creating table:", query.lastError().text())
else:
print(f"Table created successfully by {self.db_connection_name}")
query.clear()
del query
else:
print(f"Table already exists and does not need to be created by {self.db_connection_name}.")
# Finished with the query, so clear it
query.clear()
del query
def table_exists(self):
tables = self.db_connection.tables()
return "example_table" in tables
def insert_data(self, insert_data_sql, values):
query = QSqlQuery(self.db_connection)
query.prepare(insert_data_sql)
for i, value in enumerate(values):
query.bindValue(i, value)
if not query.exec_():
print("Error inserting data:", query.lastError().text())
else:
print(f"Data inserted successfully by {self.db_connection_name}")
query.clear()
del query
def close(self):
self.db_connection.close()
# QSqlDatabase.removeDatabase(self.db_connection.connectionName())
QSqlDatabase.removeDatabase("dbConnection1")
del self.db_connection
def __enter__(self):
self.connect()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
print(f"Database connection {self.db_connection_name} closed!!!")
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
1 个回答
0
关于removeDatabase的文档提到了C++,并指出了一些作用域的问题。结果发现,在Python中使用PyQt5.QtSql时,必须在self.db_connection.close()之后,和QSqlDatabase.removeDatabase("dbConnection1")之前放置del self.db_connection,这样一切就没问题了!!
我之前是在self.db_connection.close()和QSqlDatabase.removeDatabase("dbConnection1")之后才写del self.db_connection,这样做是错误的。