[PyQt] PyQt 5.7, QSqlQueryModel.data() sub-classed override bug?

Phil Thompson phil at riverbankcomputing.com
Thu May 3 13:05:11 BST 2018

On 3 May 2018, at 12:25 pm, J Barchan <jnbarchan at gmail.com> wrote:
> ​​
> I am finding (in PyQt 5.7 at least) that sub-classing QSqlQueryModel and overriding its data() method produces an incorrect result when the value retrieved from a MySQL database is NULL.​
> Full details are in https://forum.qt.io/topic/90363/inexplicable-qsqlquerymodel-handling-of-null-value, and particularly post # https://forum.qt.io/topic/90363/inexplicable-qsqlquerymodel-handling-of-null-value.  Nobody has tried it in C++ for me to date to verify, but I'm suspecting this might be a PyQt bug?
> Briefly:
> My SELECT query returns a column which is NULLable, and has NULL as its value.  Where I expect "blank" as the end value, I actually get, for example, 0 if the column type is int or '' if the type is string, etc.
> This is when I sub-class QSqlQueryModel.  If all I have is:
> class DBQueryModel(QtSql.QSqlQueryModel):
>     def __init__(self, parent=None):
>         super().__init__(parent)
> I get the "NULL"/"blank".  However, as soon as I add just:
> def data(self, index: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole) -> typing.Any:
>     return super().data(index, role)
> I get those values instead of NULL.
> Note that my override is based on the Qt definition of the method at http://doc.qt.io/qt-5/qsqlquerymodel.html#data:
> QVariant QSqlQueryModel::data(const QModelIndex &item, int role = Qt::DisplayRole) const
> Note that the default for role is Qt::DisplayRole.  However, in QtSql.py I see:
> def data(self, QModelIndex, role=None): # real signature unknown; restored from __doc__
>     """ data(self, QModelIndex, role: int = Qt.DisplayRole) -> Any """
>     pass
>  You will notice that the comment shows the default should be Qt.DisplayRole, but the declaration defaults it to None instead.

What is QtSql.py?

If you want to know the signature of a method pss it to help().

> I don't know enough to be sure, but would that be the underlying cause of the unexpected behaviour?
> FWIW, I have tried making my override be:
> def data(self, index: QtCore.QModelIndex, role=None)
> instead, but same bad behaviour.
> 1. Is this indeed a bug in PyQt, and the cause of my issue?

No and no.

> 2. If so, I presume you (Phil!) will be kind enough to fix.  However, for my part I am stuck with PyQt 5.7 for the foreseeable future.  If the fix is indeed to change code in the latest/next release, is there anything I can do in existing code (my override) to make it work in 5.7, as a workaround?  (in real code I need the override, as I do other processing)
> My coding has come to halt as I cannot proceed without a fix.  So I should be obliged for any early response as to whether this is the cause of my woes.  I do realise PyQt support/fixes are quite voluntary, and so thank whoever in advance!


More information about the PyQt mailing list