PostgreSQL, Qt, Базы данных

Qt: Резервная копия pg_dump БД PostgreSQL в Windows

Пример того, как можно реализовать резервное копирование базы данных PostgreSQL в Qt. Создается batch-файл, где вызывается утилита pg_dump.

//QString name - имя базы данных для создания копии
//file - "куда складывать" бэкап
bool myClass::backupDatabase(QString name, QString file)
{
    QString binDir = postgresBinDirectory();
    if (binDir.isEmpty()) {
        error(tr("Системный каталог bin сервера не найден. "
				 "Операция восстановления базы данных "
				 "%1 из резервной копии %2 прервана")
              .arg(name).arg(file));
        return false;
    }
    if (file.isEmpty()) {
        QDir dir(QCoreApplication::applicationDirPath()+
				 "/db_dumps/");
        if (!dir.exists())
            dir.mkpath(QCoreApplication::applicationDirPath()+
					   "/db_dumps/");
        file = QString("%1/%2-%3.dump")
                .arg(QCoreApplication::applicationDirPath()+
					 "/db_dumps")
                .arg(name)
                .arg(QDateTime::currentDateTime()
					 .toString("yyyyMMddhhmm"));
    }
    QString text = QString(
		"@ECHO OFF \n"
        "cd /d %1 \n"
        "pg_dump -Fc -U %4 -Z 9 -v %2 > \"%3\" \n"
        "set /p id=\"Press Enter to exit...\"\n")
            .arg(binDir)
            .arg(name)
            .arg(file)
            .arg(postgresUser);
    QString fileName = QString("%1-dump.bat")
            .arg(name);
	//запись Значения строки text в файл *.bat
    if (!writeBatFile(text, fileName, 
				 QCoreApplication::applicationDirPath()+"/temp"))
		return;
	//обновление файла паролей pgpass
    updatePgPassFile(QString("%1:%2:%3:%4:%5")
                     .arg(host,
                          ui->port->text(),
                          name,
                          postgresUser,
                          ui->password->text()));
	//вызов созданного batch файла
    system(qPrintable("cmd.exe /c \""+
                      QDir::toNativeSeparators(
                          QString("%1/%2")
                          .arg(QCoreApplication::applicationDirPath()+
							   "/temp")
                          .arg(fileName)+"\"")));
	//если файл бэкапа имеет ненулевой размер
    return QFileInfo(file).size() > 0;
}

Как узнать путь к каталогу bin сервера PostgreSQL, подробно написано здесь: Путь к каталогу bin PostgreSQL Windows. При условии известности имени пользователя и его пароля можно запустить утилиту pg_dump без необходимости авторизации пользователем при наличии соответствующей строки подключения в файле паролей pgpass, про что подробно писала в этой статье: Файл паролей PostgreSQL pgpass в Windows. В вышеприведенном коде используется функция updatePgPassFile(QString), код которой можно найти по обозначенной ссылке.

Более ранняя статья на схожую тему: Резервное копирование базы данных по расписанию: MS SQL Server и PostgreSQL

PostgreSQL, Qt, Базы данных

Файл паролей PostgreSQL pgpass в Windows

Для восстановления базы данных из резервной копии используется исполняемый файл сервера pg_restore. Если в настройках сервера выставлена авторизация по имени и паролю, то при использовании утилиты необходимо вводить пароль при каждой операции восстановления БД из бэкапа. Что не подходит в случае пакетной операции, например, или когда операция должна производится без взаимодействия с пользователем в этом ключе. Тогда сервер использует файл паролей pgpass. Он может и отсутствовать. Что тогда делать? Создать и обновлять. Продолжить чтение «Файл паролей PostgreSQL pgpass в Windows»

PostgreSQL, Qt, Базы данных

Путь к каталогу bin PostgreSQL Windows

Задача: получить значение пути к каталогу бинарников сервера — к каталогу bin. Путь к каталогу data, как и прочие значения параметров времени выполнения, найти совершенно несложно: достаточно выполнить запрос show, воспользоваться функцией current_setting() или обратиться к представлению pg_settings:

show data_directory;
select current_setting('data_directory');
select setting from pg_settings 
   where name = 'data_directory';
Три равнозначных примера получения значения пути к каталогу data

Еще парочку примеров показывала вот в этой записи: Количество подключений к БД PostgreSQL.

С значением пути к каталогу bin не все так просто — запросом его не получишь. Но можно узнать из реестра. В реестре не хранится чистый ключ со значением пути к каталогу, к сожалению, но можно узнать путь к исполняемому файлу службы сервера.

Итак, интересующий нас ключ: Продолжить чтение «Путь к каталогу bin PostgreSQL Windows»

Microsoft SQL Server, PostgreSQL, Qt, SQL, Базы данных

Лучшие записи 2019 года

Продолжим традицию: ниже темы, имеющие наилучшую статистику посещений за 2019 год. Пост за прошлый год: Лучшие записи за 2018 год

  1. Основы баз данных. ER-модель (сущность-связь)
  2. Добавление данных в таблицу QTableWidget. Очистка таблицы
  3. Функция, возвращающая таблицу returns table — в PostgreSQL и MS SQL Server
  4. PostgreSQL: unnest(array)
  5. PostgreSQL: Размер таблиц и базы данных
  6. PostgreSQL: Узнать данные о колонках таблицы
  7. Получить значения полей выделенной строки QTableView
  8. Qt. Динамическое создание виджетов на форме
  9. Триггеры в PostgreSQL
  10. Подключение к базе данных в Qt
Qt, Базы данных

Добавление данных запроса в таблицу QTableWidget

Здесь: Добавление данных в таблицу QTableWidget. Очистка таблицы — я рассказала, как заполнить таблицу QTableWidget данными из объекта QMap. Можно сказать, через годы и расстояния :), я решила чуть больше развернуть эту тему и показать, как организовать добавление данных запроса в таблицу. Для тех, кому по какой-то причине нужно использовать объект QTableWidget вместо QTableView. Продолжить чтение «Добавление данных запроса в таблицу QTableWidget»

PostgreSQL, SQL, Базы данных

Что быстрее: where или join?

Начнем с того, что, грубо говоря, «where» и «join» — не то же самое. Предложение where накладывает на выборку некое условие, а join — объединяет данные некоторых таблиц по некоторым условиям. Но если свести задачу к выводу данных из двух (или более) таблиц по условию, то результат будет в обоих случаях окажется идентичным. Сегодня хотелось бы выяснить, какую конструкцию использовать оптимальнее в данном случае.

Для теста буду использовать все те же таблицы из записи Оптимизация запросов PostgreSQL с explain analyze. В таблицу phonebook добавим новое поле phone_number (номер телефона): Продолжить чтение «Что быстрее: where или join?»

PostgreSQL, SQL, Базы данных

Оптимизация запросов PostgreSQL с explain analyze

Один недавний занимательный разговор на тему SQL вообще и оптимизации запросов — в частности, натолкнул меня на исследование быстродействия выполнения некоторого типа запросов. Потому что я не была уверена в этом вопросе. И мне это не понравилось 🙂 Специально для такого дела создала БД с 3 таблицами. В этом посте буду использовать только 2 из них, возможно, 3-ю задействую в других тестах. Для работы воспользуемся командой explain analyze.

Первая таблица cities содержит минимальную информацию о некоторых городах. Таблица people — о некоторых людях. И таблица phonebook хранит данные телефонного справочника. PostgreSQL 10. Продолжить чтение «Оптимизация запросов PostgreSQL с explain analyze»

Qt, SQL, Базы данных, Портфолио

Лучшие записи за 2018 год

Без лишних слов. Вот топ 10 записей 2018 года:

  1. Добавление данных в таблицу QTableWidget. Очистка таблицы
  2. Qt. Динамическое создание виджетов на форме
  3. Подключение к базе данных в Qt
  4. Основы баз данных. ER-модель (сущность-связь)
  5. АС «Складской учет». C++ Builder + MySQL
  6. Получить значения полей выделенной строки QTableView
  7. Отображение данных выборки в виджете QTableView
  8. Значения ячеек выделенных строк QTableView
  9. Контекстное меню в Qt. Popup Menu
  10. Кнопки QMessageBox на русском языке
Microsoft SQL Server, PostgreSQL, Qt, Базы данных

Резервное копирование базы данных по расписанию: MS SQL Server и PostgreSQL

Резервное копирование базы данных по расписанию: MS SQL Server и PostgreSQLНе во всех СУБД есть возможность настроить Резервное копирование базы данных по расписанию штатными средствами. Например, в Microsoft SQL Server это делается без проблем, а вот в PostgreSQL такой возможности «из коробки» нет.

Но выход есть: создать файл сценария и добавить его исполнение в расписание задач в Windows.

В переменных database, host, port, userName, bin, backupDir будут храниться значения имени базы данных, сервера, порта, имени пользователя БД, путь к bin папке PostgreSQL и директории сохранения резервных копий соответственно.

Пусть значение driver = 0 будет отвечать за PostgreSQL, а 1 — за Microsoft SQL Server.

Определим текст *.bat-файла:

QString batText = "@ECHO OFF \n"
        "SET dmpfile="+database+"-FullBackup-%DATE:~6,4%-%DATE:~3,2%-%DATE:~0,2% \n"
        "IF \"%TIME:~0,1%\"==\" \" (SET dmpfile=%dmpfile%-0%TIME:~1,1%) ELSE (SET dmpfile=%dmpfile%-%TIME:~0,2%) \n"
        "SET dmpfile=%dmpfile%-%TIME:~3,2%-%TIME:~6,2%.backup \n"
        "set text = Begin to backup... \n"
        "echo %text% \n";
if (driver==0)
       batText += QString(
           "cd %1\ \n"
           "pg_dump.exe --host %2 --port %3 --username %4 --no-password --format" 
		   "custom --blobs --verbose --file \"%5\\%dmpfile%\" %6")
            .arg(bin, host, port, userName, 
				 backupDir.replace("/", "\\"), database);
 else
       batText += QString("SQLCMD -S %1 -E -Q \"BACKUP DATABASE %2 "
           "TO DISK = '%3/%dmpfile%' "
           "WITH INIT, NOFORMAT, SKIP, NOUNLOAD\"")
                .arg(host, database, backupDir);

Имя файла резервной копии будет иметь при этом подобный вид: DatabaseName-FullBackup-2018-08-07 -11-23-38.backup, то есть имя базы данных, FullBackup + таймстемп.

Далее запишем текст в файл: Продолжить чтение «Резервное копирование базы данных по расписанию: MS SQL Server и PostgreSQL»

Microsoft SQL Server, PostgreSQL, Базы данных

Триггер на групповую вставку в таблицу в Microsoft SQL Server

Многие СУБД (например, MySQL, PostgreSQL и т.д.) умеют правильно обрабатывать события по групповой вставке данных в таблицы. Но не все. Например, триггер на групповую вставку в таблицу в Microsoft SQl Server будет отличаться. Рассмотрим примеры запросов:

insert into people
select name, surname, age from portfolio;

Или такой:

insert into people(name, surname, age) values
('John', 'Smith', 12),
('Ann', 'Black', 29),
('Samantha', 'Doeson', 38);

Продолжить чтение «Триггер на групповую вставку в таблицу в Microsoft SQL Server»