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

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

SQLite, QT

Добрый день.

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

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

bool Model::save_to_db(Data *item)
{   
    QSqlQuery query;
    query.setForwardOnly(true);

    query.prepare("INSERT INTO myDB (code, date, person, description)"
                              "VALUES (:code, :date, :person, :description)");

    query.bindValue(":code", item->Code());
    query.bindValue(":date", item->Date());
    query.bindValue(":person", item->Person());
    query.bindValue(":description", item->Description());

    if(query.exec()) return true;

    qCritical() << query.lastError().databaseText();
    qCritical() << query.lastError().driverText();
    qCritical() << query.lastError().nativeErrorCode();

    return false;
}

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

bool Model::update_in_db(Data *item)
{
    QSqlQuery query;
    query.setForwardOnly(true);
    query.prepare("UPDATE myDB SET      \n"
                  " code = :code,                     \n"
                  " date = :date,                                \n"
                  " person = :person,                        \n"
                  " description = :description            \n"
                  "WHERE id = :id;                                \n"
                  );

    query.bindValue(":code", item->Code());
    query.bindValue(":date", item->Date());
    query.bindValue(":person", item->Person());
    query.bindValue(":description", item->Description());

    if(query.exec()) {
        return true;
    } else {
        qCritical() << query.lastError().databaseText();
        qCritical() << query.lastError().driverText();
        qCritical() << query.lastError().nativeErrorCode();

        return false;
    }
}

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

Model::delete_from_db()
{
    QSqlQuery query;
    query.setForwardOnly(true);
        query.prepare("DELETE FROM myDB WHERE id = :ID ;");
        query.bindValue(":ID", currentIndex.row());//индекс сигналом по клику 
        //передаю из MainWindow, так как представление находится в классе MainWindow

        if(!query.exec()){
            qCritical() << query.lastError().databaseText().toUtf8().data();
            qCritical() << query.lastError().driverText();
            qCritical() << query.lastError().nativeErrorCode();
            return false;
        } else {
            return true;
        }
        return false;
}

Исходный код

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

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

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

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, на сколько помню, удаляет данные из поля, чтоб изменить размер и удалить пустые строки нужно доболнительно делать вакуум

            Комментарии

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

            C++ - Тест 002. Константы

            • Результат:16баллов,
            • Очки рейтинга-10
            B

            C++ - Тест 001. Первая программа и типы данных

            • Результат:46баллов,
            • Очки рейтинга-6
            FL

            C++ - Тест 006. Перечисления

            • Результат:80баллов,
            • Очки рейтинга4
            Последние комментарии
            k
            kmssr9 февраля 2024 г. 5:43
            Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
            АК
            Анатолий Кононенко5 февраля 2024 г. 12:50
            Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
            EVA
            EVA25 декабря 2023 г. 21:30
            Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
            J
            JonnyJo25 декабря 2023 г. 19:38
            Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
            G
            Gvozdik19 декабря 2023 г. 8:01
            Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
            Сейчас обсуждают на форуме
            P
            Pisych27 февраля 2023 г. 15:04
            Как получить в массив значения из связанной модели? Спасибо, разобрался:))
            AC
            Alexandru Codreanu19 января 2024 г. 22:57
            QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…
            BlinCT
            BlinCT27 декабря 2023 г. 19:57
            Растягивать Image на парент по высоте Ну и само собою дял включения scrollbar надо чтобы был Flickable. Так что выходит как то так Flickable{ id: root anchors.fill: parent clip: true property url linkFile p…
            Дмитрий
            Дмитрий10 января 2024 г. 15:18
            Qt Creator загружает всю оперативную память Проблема решена. Удалось разобраться с помощью утилиты strace. Запустил ее: strace ./qtcreator Начал выводиться весь лог работы креатора. В один момент он начал считывать фай…
            Evgenii Legotckoi
            Evgenii Legotckoi12 декабря 2023 г. 17:48
            Побуквенное сравнение двух строк Добрый день. Там случайно не высылается этот сигнал textChanged ещё и при форматировани текста? Если решиать в лоб, то можно просто отключать сигнал/слотовое соединение внутри слота и …

            Следите за нами в социальных сетях