QSqlRelationalTableModel — вставить запись больше 256

#qt #sqlite #qsqlquery #qsqltablemodel #qsqldatabase

#qt #sqlite #qsqlquery #qsqltablemodel #qsqldatabase

Вопрос:

У меня есть таблица node={id, name} и сегмент таблицы = {id, nodeFrom,nodeTo} в базе данных SQLite, где node.id и segment.id являются полями АВТОИНКРЕМЕНТА.

Я создаю QSqlTableModel для узла следующим образом:

 nodeModel = new QSqlTableModel(this,db);
nodeModel->setTable("Node");
nodeModel->setEditStrategy(QSqlTableModel::OnFieldChange);
 

и я использую следующий код для вставки узлов:

 int addNode(QString name) {
    QSqlRecord newRec = nodeModel->record();
    newRec.setGenerated("id",false);
    newRec.setValue("name",name);
    if (not nodeModel->insertRecord(-1,newRec))
        qDebug() << nodeModel->lastError();
    if (not nodeModel->submit())
        qDebug() << nodeModel->lastError();
    return nodeModel->query().lastInsertId().toInt();
}
 

Кажется, это работает. Теперь для сегментов я определяю QSqlRelationalTableModel следующим образом:

 segModel = new QSqlRelationalTableModel(this,db);
segModel->setTable("Segment");
segModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
segModel->setRelation(segModel->fieldIndex("nodeFrom"),
                                QSqlRelation("Node","id","name"));
segModel->setRelation(segModel->fieldIndex("nodeTo"),
                                QSqlRelation("Node","id","name"));
 

И тогда у меня есть следующий код для вставки сегментов:

 int addSegment(int nodeFrom, int nodeTo) {
    QSqlRecord newRec = segModel->record();
    newRec.setGenerated("id",false);
    newRec.setValue(1,nodeFrom);
    newRec.setValue(2,nodeTo);
    if (not segModel->insertRecord(-1,newRec))  // (*)
        qDebug() << segModel->lastError();
    if (not segModel->submitAll())
        qDebug() << segModel->lastError();  // (*)
}
 

Я могу успешно добавить 280 узлов с помощью AddNode(). Я также могу успешно добавлять сегменты, если nodeFrom<=256 и nodeTo<=256. Для любого сегмента, ссылающегося на узел, больший или равный 256, я получаю

 QSqlError("19", "Unable to fetch row", "Segment.nodeTo may not be NULL")
 

в одной из строк, отмеченных знаком (*) функции addSegment.

Я погуглил и обнаружил, что у людей возникают другие (явно не связанные) проблемы, когда они достигают магического количества записей 256. Похоже, ни одно решение не работает с этой конкретной проблемой.

Что я делаю не так?

Спасибо!

Ответ №1:

Причина этой ошибки заключается в void QRelation::populateDictionary() методе, который использует такой цикл for (int i=0; i < model->rowCount(); i) . Если вы используете базу данных, которая не сообщает размер обратного запроса (например, SQLite), rowCount() метод вернет это магическое 256 значение.

Вы можете решить эту проблему, заполнив модель отношений перед использованием data(...) или setData(...) . Сначала вы можете попробовать с:

 setRelation(nodeFromCol, QSqlRelation("Node", "id", "name"));
QSqlTableModel *model = relationModel(nodeFromCol);
while(model->canFetchMore())
    model->fetchMore();
 

Ответ №2:

Попробуйте этот способ исправить

 newRec.setValue(1,QVariant(nodeFrom));

newRec.setValue(2,QVariant(nodeTo));