Юрий
Aug. 17, 2019, 10:54 p.m.

Как правильно отслеживать актуальность базы данных

database

Добрый вечер.

Подскажите как правильно синхронизировать структуру БД? С другим рабочем местом.
БД MySQL.

5

Do you like it? Share on social networks!

13
Ruslan Polupan
  • Aug. 17, 2019, 11:53 p.m.

Не очень понятен вопрос. База одна или их несколько?

    Юрий
    • Aug. 18, 2019, 1:06 a.m.

    База одна.
    Как отслеживать структуру в самой БД и той которая в приложении.
    Обратился я к таблице, а ее нет в данной версии БД и приложение упало.

      Юрий
      • Aug. 18, 2019, 1:11 a.m.

      Сейчас я использую MySQL Workbench, создаю EER model и потом синхронизирую структуру БД где мне нужно, но вот хотелось бы автоматом проверять совместимость БД с приложением.
      Надеюсь правильно изложил мысль.

        Ruslan Polupan
        • Aug. 18, 2019, 1:22 p.m.

        Т.е. таблицы в БД к которым обращается приложение могут отсутсвовать?

          Юрий
          • Aug. 18, 2019, 2:53 p.m.

          Все верно.

            nayk1982
            • Aug. 19, 2019, 10:40 a.m.
            • (edited)

            Программно можно проверить существование таблицы, получить список таблиц БД, получить список полей конкретной таблицы и т.д. Это все на совести программиста и если структура БД может меняться, то такие проверки необходимо делать до обращения к таблицам, чтоб приложение не падало.

            Список таблиц в Qt: QSqlDatabase::tables(...)

              Evgenii Legotckoi
              • Aug. 19, 2019, 12:57 p.m.

              У нас в проекте создана таблица, в которой вносятся версии базы данных, в зависимости от версии используется соответствующая логика.

              В случае с Django, например, имеется таблица миграций, и каждая запись соответствует миграционному файлу. Автоматически делается проверка на структуру базы данных, и если есть изменения, то нужно применить новые миграции.

              Ещё как вариант, то дополнительно прикрутить REST API к серверу базы данных и отдавать данные в виде JSON структур. Их будет проще распрасить, чтобы приложение не падало.

                Pavel K.
                • Aug. 19, 2019, 7:47 p.m.
                1. bool YourClass::chekIfEmpty(const QString& table) {
                2. return getCount(table) == 0;
                3. }
                4. int YourClass::getCount(const QString& table, const QString& where) {
                5. QString command = QString("SELECT COUNT(*) FROM '%1'").arg(table);
                6. if (!where.isEmpty()) {
                7. command += " WHERE " + where;
                8. }
                9. execute(command);
                10. int count = 0;
                11. if (query().next()) {
                12. count = query().value(0).toInt();
                13. }
                14.  
                15. return count;
                16. }

                думаю что-то подобное)))

                  Юрий
                  • Aug. 21, 2019, 12:46 p.m.

                  Тут только получим сами таблицы, а колонки и тип данных. Таблицы не так часто меняются, а вот тип данных и колонки очень даже часто.

                    Evgenii Legotckoi
                    • Aug. 21, 2019, 1:04 p.m.

                    Вам нужно вести версионирование базы данных и в зависимости от версии использовать соответсвующую логику. Иначе никак. У нас на проекте тоже имеется проблема с версионированием в базе данных. Просто создали таблицу, которая содержит версию, и в зависимости от версии либо конвертируем поля, либо ничего не делаем, то есть игнорируем логику, либо делаем ещё что-то, что требуется.

                    То есть однозначно нужна таблица с версией базы данных.

                    Естественно, что это хорошо работает в том случае, если приложение последней версии открывает базу данных старшей версии или той же самой.

                    Старое приложение откроет новую базу данных скорее всего с ошибками. Либо после проверки предлагать обновление и ничего не делать.

                      Ruslan Polupan
                      • Aug. 21, 2019, 1:11 p.m.

                      У нас реализовано так что при запуске программа проверяет версию БД (естетсвенно она хранится в таблице) если версия БД младше то выполняется обновление бд. На каждую новую версию если изменяется структура БД создается sql файл со скриптами которые и зменяют БД 20190806_update_tanks.sql например. И программа последовательно выполняет скрипты для модификации БД и только потом запускается.

                        nayk1982
                        • Aug. 21, 2019, 1:16 p.m.

                        Если Вы разрабатываете какую-то универсальную утилиту, которая вообще не привязана к логике, тогда как вариант:
                        1. Получить список таблиц через QSqlDatabase::tables
                        2. Для каждой таблицы получить список столбцов, например так:

                        1. QSqlQuery query();
                        2. if(query.exec("select * from tableName limit 1;")) {
                        3. QSqlRecord rec = query.record();
                        4. for(int j=0; j<rec.count(); j++) {
                        5. // Тут доступ к полю, его имя, тип и т.д:
                        6. // rec.field(j).name();
                        7. // rec.field(j).type();
                        8. // etc..
                        9. }
                        10. }

                        Но вариант Евгения правильнее и логичнее если ПО делается под конкретную БД.

                          Юрий
                          • Aug. 25, 2019, 10:25 p.m.

                          В принципе я так и делаю, у меня есть таблица с номером текущей версии БД.
                          При запуске приложения происходит проверка версии БД поддерживаемой приложением.
                          Потом получаю данные в Json формате с сайта и проверяю на новые версии.
                          Если вышла новая версия, предлагаю обновиться и запускаю стандартный интерфейс (QtIFW) обновления из репозитория.

                          Спасибо, расказали подробно.

                            Comments

                            Only authorized users can post comments.
                            Please, Log in or Sign up
                            • Last comments
                            • Evgenii Legotckoi
                              April 16, 2025, 5:08 p.m.
                              Благодарю за отзыв. И вам желаю всяческих успехов!
                            • IscanderChe
                              April 12, 2025, 5:12 p.m.
                              Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
                            • AK
                              April 1, 2025, 11:41 a.m.
                              Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
                            • Evgenii Legotckoi
                              March 9, 2025, 9:02 p.m.
                              К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
                            • VP
                              March 9, 2025, 4:14 p.m.
                              Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…