1

I have a QSqlRelationalTableModel with a related table with more than 256 rows. The relation is working perfect, i have in column 1 the related values from the "relation_table"

But mapping the data in the combobox and submiting to the db by selecting in the combobox, works only for the first 256 rows.

Adding a value higher than 256 to the db by hand, the related value do not map to the combobox, but in the tableview is the relation correct.

Otherwise displays a click on the combobox all items in the list of the combobox.

I have the data from a SQLITE-database which has a this structure:

CREATE TABLE `base_table` ( `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `rel_id` INTEGER);
INSERT INTO `base_table` VALUES (1, 1);
CREATE TABLE "rel_table" ( `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `name` TEXT);
INSERT INTO `rel_table` VALUES (1,'aaa');

Here is a simple working example:

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDataWidgetMapper, QVBoxLayout,\
    QWidget, QComboBox, QApplication, QTableView, QPushButton
from PyQt5.QtSql import QSqlRelationalTableModel, QSqlRelation,\
    QSqlRelationalDelegate, QSqlDatabase


def submitModel():
    mapper.submit()
    model.submitAll()

app = QApplication(sys.argv)
window = QWidget()

combobox = QComboBox()
tableview = QTableView()
button = QPushButton('submit')
layout = QVBoxLayout()

layout.addWidget(combobox)
layout.addWidget(tableview)
layout.addWidget(button)

con = QSqlDatabase.addDatabase('QSQLITE')
con.setDatabaseName('test_db.sqlite')
con.open()

model = QSqlRelationalTableModel()
model.setTable("base_table")
model.setRelation(1, QSqlRelation("rel_table", "id", "name"))
model.select()

relation_model = model.relationModel(1)
relation_model.setSort(0, Qt.AscendingOrder)

while relation_model.canFetchMore():
    relation_model.fetchMore()

relation_model.select()

combobox.setModel(relation_model)
combobox.setModelColumn(1)

mapper = QDataWidgetMapper()
mapper.setModel(model)
mapper.setItemDelegate(QSqlRelationalDelegate())
mapper.addMapping(combobox, 1)
mapper.toFirst()

tableview.setModel(model)
tableview.setItemDelegate(QSqlRelationalDelegate(tableview))

button.clicked.connect(submitModel)

window.setLayout(layout)
window.setGeometry(300, 300, 250, 300)
window.show()
sys.exit(app.exec_())

To test the issue in the example above, you have to fill the table "rel_table" with more than 256 rows!

How can i get a correct working combobox, that displays a relation for all related items?

vezzon
  • 177
  • 1
  • 11
  • provide a [mre], what is `QSqlRelationalTableModelExtra`? – eyllanesc Jan 16 '20 at 14:37
  • Sorry, a QSqlRelationalTableModelExtra is a normal QSqlRelationalTableModel. – vezzon Jan 16 '20 at 14:40
  • then edit your question and fix this error – eyllanesc Jan 16 '20 at 14:41
  • what is `item_model`?, again: provide a [mre] – eyllanesc Jan 16 '20 at 17:38
  • I have rewritten my question and added a minimal reproducible example! Thanks a lot! – vezzon Jan 17 '20 at 09:49
  • mmm, I don't reproduce the problem. I have filled in the "rel_table" table with 512 elements and in the QComboBox I can see all the rows. – eyllanesc Jan 17 '20 at 14:45
  • Yes, you can see all rows in the Combo, but you cannot select and submit one to the db. If you write by hand one value over 256 in the db, the Combo do Not map the related value – vezzon Jan 17 '20 at 14:58
  • 1
    That you should point out clearly, in your question it only says that you will not see it but it is false, from your comment I understand that you can see it but you cannot save it in the database, and that is another problem. I recommend you edit your question and clearly state that to avoid further confusion. – eyllanesc Jan 17 '20 at 15:01
  • I have improved my question, sorry for the confusing wording – vezzon Jan 17 '20 at 15:16

1 Answers1

0

Remove relation_model.select().


TL; DR;

In the private Qt API, the populateDictionary() function is called which only loads a maximum of 256 (magic number that seems to be the number of rows obtained in each transaction) rows since it does not use canFetchMore() and fetchMore(). So it seems that the OP knows that limitation because it uses canFetchMore() and fetchMore() to load the new data but the error is to call again relation_model.select() that loads at most the first 256 elements eliminating the effect of canFetchMore() and fetchMore().

eyllanesc
  • 235,170
  • 19
  • 170
  • 241