Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

insertRecord not saving the values



    • This is my third day trying to insert record in the model, it inserts record but without the provided values. [I have tried it with 02 version of Qt]

    Please help:

    // contentModel is the subclass of QSqlTableModel
    bool contentModel::addRecord () {

    QSqlRecord newRecord = this->record();
    newRecord.setValue("id", 3); 
    newRecord.setValue("data", "chilling humanity");
    newRecord.setValue("type", "text");
    qDebug() << "field" << newRecord.value(1);   // output: chilling humanity
    
    if(this->insertRecord(-1,newRecord)) {  // new row is the third row
          qDebug() << "data => " << this->data(index(2, 1), 258);    // output: empty string
    
      }
    

    }

    QVariant contentModel::data(const QModelIndex &index, int role) const {
    QVariant value;

    if (index.isValid()) {
        if (role < Qt::UserRole) {
            value = QSqlQueryModel::data(index, role);
        } else {
            int columnIdx = role - Qt::UserRole - 1;
            QModelIndex modelIndex = this->index(index.row(), columnIdx);
            value = QSqlTableModel::data(modelIndex, Qt::DisplayRole);
        }
    }
    return value;
    

    }

    QHash<int, QByteArray> contentModel::roleNames() const {

    QHash<int, QByteArray> roles;
    roles.insert(Qt::UserRole + 1, "model_id");
    roles.insert(Qt::UserRole + 2, "model_data");
    roles.insert(Qt::UserRole + 3, "model_type");
    
    return roles;
    

    }


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Did you inspect the content of your database with an other tool to check if the insertion really did fail ?

    About your code: why don't you print the error you have on insertion failure ?

    Your data method look strange: for standard roles you are not calling the base classe implementation however for your custom roles you do. That does not look good.



  • Thank you for the feedback.

    • I am just trying to add a row in the model, saving it to database is the next step [I think]

    • insertRecord actually adds a blank row without the values

    • in data method, I am building QModelIndex according to custom role [code taken from Qt wiki]

    thanks again.


  • Lifetime Qt Champion

    If you are at the experimenting level, do not start by sub classing QSqlTableModel. Just use it to check your insertion code. Once you have that working, then you can go further.

    In any case, always do success checks and at least print the error if something goes wrong.



  • I tried as you suggested but ... same result
    [02 records are already there in database]

    QSqlTableModel contentModel(&app, db);
    contentModel.setTable("content");    //  (id, data, type)
    contentModel.select();
    contentModel.setEditStrategy(QSqlTableModel::OnManualSubmit);
    QSqlRecord rec;
    rec.setValue("id", contentModel.rowCount());
    rec.setValue("data","Weeping Monk");
    rec.setValue("type", "text");
    
    qDebug() << contentModel.insertRecord(-1, rec);   // true
    qDebug() << contentModel.submitAll();   // false
    qDebug() << contentModel.data(contentModel.index(2,1));  // QVariant(QString, "")
    qDebug() << "ERROR: " << contentModel.lastError();  // ERROR:  QSqlError("", "No Fields to update", "")

  • Lifetime Qt Champion

    Are you sure your database connection is working ?
    Are you sure your QSqlTableModel has no error ?



  • yes, I am loading 02 rows in listview and once I was able to insert one record in database by manually calling setData [in my previous example of subclassing]



  • Minimal code for reproduction:
    show 02 rows in view but does not insert the third one

    #include <QApplication>
    #include <QSplitter>
    #include <QStringListModel>
    #include <QListView>
    #include <QSqlDatabase>
    #include <QtDebug>
    #include <QTableView>
    #include <QSqlTableModel>
    #include <QSqlRecord>

    int main(int argc, char *argv[])
    {
    QSqlDatabase db;

    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("path-to/db.db");
    db.open();
    if(db.isOpen()) {
        qDebug("database is opened");
    }
    
    QApplication a(argc, argv);
    
    
    QTableView contentView;
    
    QSqlTableModel contentModel(&a, db);
    contentModel.setEditStrategy(QSqlTableModel::OnRowChange);
    contentModel.setTable("content");  // (id: int PK, data: text, type: text)
    contentModel.select();
    
    contentView.setModel(&contentModel);
    contentView.hideColumn(contentModel.fieldIndex("id"));
    contentView.hideColumn(contentModel.fieldIndex("type"));
    contentView.show();
    
    
    QSqlRecord rec;
    //  rec.setValue("id", contentModel.rowCount());
    rec.setValue("data","Weeping Monk");
    rec.setValue("type", "text");
    
    contentModel.insertRecord(-1, rec);
    
    return a.exec();
    

    }



  • It is actually working with insertRows() and setData() but not with record ... very strange


  • Lifetime Qt Champion

    First rule: QApplication shall be the first thing you create. It does some initialisation of internal stuff that are required. Here again, you do not do any checks nor print any error if things fail.



  • Qt does not throw exceptions .. we are left to rely on function's return value and the lastError() ... there is no insight how something is mechanized under the hood.


  • Lifetime Qt Champion

    You have the full Qt sources at your disposal if you are curious about the gory details.
    The documentation is pretty complete and contains a lot of examples.



  • Thanks a lot again for quick response, feedback and support.


Log in to reply