VB
16 сентября 2020 г. 18:23

QSqlTableModel не удаётся редактировать и удалять данные

SQLite, QT

Добрый день.

Впервые решил использовать для создания базы данных связку модели и представления. За основу взял SQLite. Класс Model унаследован от QSqlTableModel. Способ подключения базы данных и связки модели с представлением взял с этого сайта, немного изменив. Но, к сожалению, не работает обновление данных и удаление. Чтобы я ни делал, не получается. Может кто-нибудь знает решение?

Вот этот метод работает:

  1. bool Model::save_to_db(Data *item)
  2. {
  3. QSqlQuery query;
  4. query.setForwardOnly(true);
  5.  
  6. query.prepare("INSERT INTO myDB (code, date, person, description)"
  7. "VALUES (:code, :date, :person, :description)");
  8.  
  9. query.bindValue(":code", item->Code());
  10. query.bindValue(":date", item->Date());
  11. query.bindValue(":person", item->Person());
  12. query.bindValue(":description", item->Description());
  13.  
  14. if(query.exec()) return true;
  15.  
  16. qCritical() << query.lastError().databaseText();
  17. qCritical() << query.lastError().driverText();
  18. qCritical() << query.lastError().nativeErrorCode();
  19.  
  20. return false;
  21. }

Вот этот не работает (данные добавляются в представление, но не в базу):

  1. bool Model::update_in_db(Data *item)
  2. {
  3. QSqlQuery query;
  4. query.setForwardOnly(true);
  5. query.prepare("UPDATE myDB SET \n"
  6. " code = :code, \n"
  7. " date = :date, \n"
  8. " person = :person, \n"
  9. " description = :description \n"
  10. "WHERE id = :id; \n"
  11. );
  12.  
  13. query.bindValue(":code", item->Code());
  14. query.bindValue(":date", item->Date());
  15. query.bindValue(":person", item->Person());
  16. query.bindValue(":description", item->Description());
  17.  
  18. if(query.exec()) {
  19. return true;
  20. } else {
  21. qCritical() << query.lastError().databaseText();
  22. qCritical() << query.lastError().driverText();
  23. qCritical() << query.lastError().nativeErrorCode();
  24.  
  25. return false;
  26. }
  27. }

И удаление не работает:

  1. Model::delete_from_db()
  2. {
  3. QSqlQuery query;
  4. query.setForwardOnly(true);
  5. query.prepare("DELETE FROM myDB WHERE id = :ID ;");
  6. query.bindValue(":ID", currentIndex.row());//индекс сигналом по клику
  7. //передаю из MainWindow, так как представление находится в классе MainWindow
  8.  
  9. if(!query.exec()){
  10. qCritical() << query.lastError().databaseText().toUtf8().data();
  11. qCritical() << query.lastError().driverText();
  12. qCritical() << query.lastError().nativeErrorCode();
  13. return false;
  14. } else {
  15. return true;
  16. }
  17. return false;
  18. }

Исходный код

Спасибо за внимание!

3

Вам это нравится? Поделитесь в социальных сетях!

5
Evgenii Legotckoi
  • 17 сентября 2020 г. 12:20
  • Ответ был помечен как решение.

Добрый день.

Метод update_in_db скорее всего не работает из-за наличия знаков каретки \n , а также из-за того, что нет bind для ID.

Что касается delete_from_db , то тут я не уверен, в чём может быть ошибка. Что вываливается в вывод qCritical?

    VB
    • 17 сентября 2020 г. 14:38
    • (ред.)

    Да, редактирование теперь работает! Спасибо!
    По поводу удаления, причина в том, что индекс в представлении отличается от id в базе. Нужно брать id для удаления из базы, а не из представления. Всё, задача решена!

      Evgenii Legotckoi
      • 17 сентября 2020 г. 14:43

      Если через раз, то дело скорее всего в том, что обычно ID является автоинкрементируемым столбцом, который всегда растёт, даже если какие-то строки удалялись из базы данных. Если у вас было 4 записи с ID: 1, 2, 3, 4 и вы удалили 4-й, то следующий ID будет 5 и в таблице будут 1, 2, 3, 5.

      В данном случае currentIndex.row() не отвечает ID, это просто номер строки в таблице. Вам нужно сначала получить ID записи, можно это сделать через метод data, просто нужно иметь столбки с ID, можно сделать его скрытым. А потом уже делать удаление по этому id

        VB
        • 30 октября 2020 г. 18:01

        А удаление всё же не работает. Понял это когда по аналогии с этим проектом создал проект с картинками. При удалении элементов размер базы данных не меняется. То есть в представлении элемент показываться не будет, но из базы данных по видимому не удаляется.

          Алексей Внуков
          • 30 октября 2020 г. 18:56
          • (ред.)

          а проверить просто что находится в базе? и вообще SQLite, на сколько помню, удаляет данные из поля, чтоб изменить размер и удалить пустые строки нужно доболнительно делать вакуум

            Комментарии

            Только авторизованные пользователи могут публиковать комментарии.
            Пожалуйста, авторизуйтесь или зарегистрируйтесь