I love all of the goodness you get from QSqlDatabase and QSqlQuery and various models. But I would really like exceptions to be thrown when errors occur. So I thought maybe I could subclass QSqlDatabase to throw an exception when the open() method fails:
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_())
The main issue I have is I don't know how to handle the addDatabase
method. It returns an instance of QSqlDatabase. But I want it to return an instance of ExceptionalDatabase. How would I get an instance of my class from addDatabase
?
First of all addDatabase is a static method so you should not pass it self. On the other hand, a workaround is to establish the __class__ of the QSqlDataBase:
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())