[PyQt] QSqlTableModel, PostgreSQL: Model forgets data after submitting
Sibylle Koczian
nulla.epistola at web.de
Mon Aug 17 16:41:03 BST 2015
Hello,
when I insert data into a PostgreSQL database table using a
QSqlTableModel they are written to the database, but I can't see them in
the application after submitting. This happens with tables whose primary
key has type SERIAL, it doesn't happen if the primary key is inserted by
hand.
This doesn't happen with SQLite databases and it doesn't happen if I use
PyQt4. That's why I think it might be a bug in QPSQL. If that's true,
what should I do? I've next to no knowledge of C++, so I don't think I
could do a proper bug report.
After calling model.select() the data are visible again, but the
selection in a QTableView or similar is lost.
I've attached a small example which uses the following table:
CREATE TABLE person (idp SERIAL PRIMARY KEY, fullname VARCHAR(50))
This should run (after adapting createPGConnection, of course) and show
the problem. The table can be created by the script (uncomment the call
to createTable() in main()).
#!/usr/bin/env python3
# newrecords_test.py
# Adding new records to a QSqlTableModel connected to a PostgreSQL database.
import os
import sys
import logging
from PyQt5 import QtCore
from PyQt5 import QtSql
modlog = logging.getLogger(__name__)
def createPGConnection():
db = QtSql.QSqlDatabase.addDatabase("QPSQL")
db.setDatabaseName("xxx")
db.setHostName("localhost")
db.setUserName("xxx")
db.setPassword("xxx")
return db
def createTable():
createstmt = """CREATE TABLE person (idp SERIAL PRIMARY KEY,
fullname VARCHAR(50))"""
query = QtSql.QSqlQuery()
ok = query.exec_(createstmt)
if ok:
modlog.debug("Successfully created table 'person'")
else:
modlog.error(query.lastError().text())
def setupModel(tablename):
model = QtSql.QSqlTableModel()
model.setTable(tablename)
model.setEditStrategy(QtSql.QSqlTableModel.OnRowChange)
model.setHeaderData(0, QtCore.Qt.Horizontal, "ID")
model.setHeaderData(1, QtCore.Qt.Horizontal, "Full name")
model.select()
return model
def addNewName(newname, model):
zz = model.rowCount()
ok = model.insertRow(zz)
if not ok:
modlog.error(model.lastError().text())
ok = model.setData(model.index(zz, 1), newname)
if not ok:
modlog.error(model.lastError().text())
return zz
def showRow(msg, row, model):
print("{}, new record in row {}: {} ({})".format(msg, row,
model.data(model.index(row, 1)),
model.data(model.index(row, 0))))
def main():
personModel = setupModel("person")
row = addNewName("John B. Doe", personModel)
showRow("Before submit", row, personModel)
ok = personModel.submit()
if not ok:
modlog.error(personModel.lastError().text())
showRow("After submit", row, personModel)
personModel.select()
showRow("After select", row, personModel)
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
app = QtCore.QCoreApplication(sys.argv[1:])
db = createPGConnection()
ok = db.open()
if not ok:
modlog.error(db.lastError().text())
sys.exit(1)
# if desired, uncomment for first run:
# createTable()
main()
If I run this, using Windows 7, 64 bit, with Python 3.4.3 and PyQt 5.5,
I get this output:
DEBUG:__main__:Before submit, new record in row 2: John B. Doe (0)
DEBUG:__main__:After submit, new record in row 2: None (None) <---- ???
DEBUG:__main__:After select, new record in row 2: John B. Doe (3)
More information about the PyQt
mailing list