PyQt 子类化 QSqlDatabase 以产生异常

PyQt subclassing QSqlDatabase to make exceptions

我喜欢您从 QSqlDatabase 和 QSqlQuery 以及各种模型中获得的所有好处。但我真的很希望在发生错误时抛出异常。所以我想也许我可以 subclass QSqlDatabase 在 open() 方法失败时抛出异常:

from PyQt5.QtWidgets import (QApplication, QMainWindow, QTableView)
from PyQt5.QtSql import (QSqlQuery, QSqlQueryModel, QSqlDatabase)
import sys

class ExceptionalDatabase(QSqlDatabase):

    #def addDatabase(self, *args, **kwargs):
        # what to put here? I need to return an instance of
        # ExceptionalDatabase, right?
        #
        # this doesn't work:
        # return super(ExceptionalDatabase, self).addDatabase(*args, **kwargs)

    def open(self, user=None, pwd=None):
        # this method will never be called, because addDatabase will
        # return a QSqlDatabase instance
        if user is None:
            retval = super(ExceptionalDatabase, self).open()
        else:
            retval = super(ExceptionalDatabase, self).open(user=user, password=pwd)

        if retval == False:
            raise ValueError(self.lastError().text())

app = QApplication(sys.argv)

fid = open('example.db', 'w')
fid.close()

db = ExceptionalDatabase.addDatabase("QSQLITE")
db.setDatabaseName('example.db')
db.open()

db.close()

sys.exit(app.exec_())

我遇到的主要问题是我不知道如何处理 addDatabase 方法。它 return 是 QSqlDatabase 的一个实例。但我希望它成为 return ExceptionalDatabase 的一个实例。我如何从 addDatabase 获得我的 class 的实例?

首先,addDatabase 是一个静态方法,所以你不应该自己传递它。另一方面,解决方法是建立 QSqlDataBase 的 __class__:

class ExceptionalDatabase(QSqlDatabase):
    @staticmethod
    def addDatabase(*args, **kwargs):
        db = QSqlDatabase.addDatabase(*args, **kwargs)
        db.__class__ = ExceptionalDatabase
        return db

    def open(self, user=None, pwd=None):
        if user is None:
            retval = super(ExceptionalDatabase, self).open()
        else:
            retval = super(ExceptionalDatabase, self).open(user=user, password=pwd)
        if retval == False:
            raise ValueError(self.lastError().text())