PDA

View Full Version : setData fails in QSqlRelationalTableModel



thePoet
4th July 2009, 17:22
I have a QSqlRelationalTableModel that references a simple lookup table containing a primary key named id of type text (string uuid) and a name field of type text. When I insert into the QSqlRelationalTableModel, it only uses the most recently created id in the lookup table.

When I insert a new item in the lookup table, and then attempt to add a new item in the QSqlRelationalTableModel, the new item regularly fails on setData on the column with the relationship. It doesn't always fail, but it usually does. If it fails using that key, it will always fail with that key. If it doesn't, it will always succeed with that key.



if( !_itemModel->setData(_itemModel->index(0,4), _locationUuid) )
{
QMessageBox::critical(0, "set data 4 failed",
_itemModel->lastError().text(), QMessageBox::Cancel);
}


I can't figure out what the cause is. The _itemModel->lastError() doesn't return any text. If I look at the table with a third party tool, the item was properly inserted into the lookup table. Am I supposed to do something to the model to tell it that the data it references was updated?

Also, the lookup table is being managed by a QSqlTableModel. The insert looks like this:



if( !_locationModel->insertRow(0) )
{
QMessageBox::critical(0, "insert failed",
_locationModel->lastError().text(), QMessageBox::Cancel);
}

if( !_locationModel->setData(_locationModel->index(0,0), _locationUuid) )
{
QMessageBox::critical(0, "set data 1 failed",
_locationModel->lastError().text(), QMessageBox::Cancel);
}

if( !_locationModel->setData(_locationModel->index(0,1),location) )
{
QMessageBox::critical(0, "set data 2 failed",
_locationModel->lastError().text(), QMessageBox::Cancel);
}

if( !_locationModel->submitAll() )
{
QMessageBox::critical(0, "submit failed",
_locationModel->lastError().text(), QMessageBox::Cancel);
}

wysota
5th July 2009, 03:03
Did you reset the model after adding the data to one of the tables in the database? There is no notification mechanism running so if you add some data to a database without letting the model know what you did, it will not detect the changes by itself.

thePoet
5th July 2009, 23:16
I tried calling select on _itemModel (the QSqlRelationalTableModel) after adding an item to the lookup table. That didn't seem to help at the time. Is there something else I should be looking at?

wysota
6th July 2009, 07:29
As far as I remember calling select() again is a no-op. Try calling clear() and then select(). Better yet, add records to the lookup table through the relation model (QSqlRelationalModel::relationModel()) instead of manual calls, then you shouldn't need to synchronize anything.

thePoet
6th July 2009, 18:45
I think that last one will work. I didn't realize you could get the internal QSqlTableModel of the related table. I'll try it tonight.

This does bring up an interesting question. How should you handle a scenario where there are two QSqlRelationalTableModels referring to the same lookup table? It appears that they would each have their own QSqlTableModel wrapping the lookup table, in which case one would always have to be manually updated, or is that somehow shared between them. It doesn't appear you can manually set the QSqlTableModel that manages the represented table.

wysota
6th July 2009, 19:06
Yes, seems so. You could work around it by working with QSqlTableModel and provide a custom "intelligent" delegate that would do lookups for both models using its own internal (single) model.

thePoet
8th July 2009, 04:27
I finally got it to work. I used the table model returned by relationModel to insert into the lookup table. I also had to call submitAll on the QSqlRelationalTableModel itself (after calling it on the relation tableModel) to get that table to notice that lookup table had changed. I don't know if calling submitAll on the relation tableModel is actually rquired, but it had to be talled on the QSqlRelationalTableModel.