Создаем первый bat-файл или вспоминаем создание и восстановление баз MySql из командной строки

январь 6 , 2016
Метки:

bat-файлПонадобилось мне давеча из одного sql-ного дамп-файла создать несколько разных баз с одинаковым содержимым из оного дампа. Не спрашивайте зачем, у всех свои причуды. Так как заранее количество баз и их названия были неизвестны, то было принято политическое решение написать для этого дела маленький (или как уж получится) батник. Как всегда, взявшись за что-то новенькое, даже самое простенькое дело, находится несколько забавных особенностей, которые хочется сохранить и не забывать. Далее описываю, что из этого получилось...

Что мы имеем.

Некий файл dump.sql - дамп базы, всякие create table и insert into, не суть важно.
И в отдельном файле databases.txt есть список с названиями этих самых баз.
Нам нужно считать этот файл построчно, создать для каждого названия соответствующую базу и загнать в нее содержимое dump.sql.
Примечание: в нашем примере все файлы лежат в одной папке

Как это делаем.

Как считать файл, открыв гугл, нашел сразу.
Небольшой заминкой оказалось то, что выполнять sql-команды из файла получилось легко, а вот прямо из командной строки выполнить простой sql-запрос не удалось.
Казалось бы есть у mysql параметр -e, который позволяет выполнять запросы примерно так:

        mysql -uuser -ppassword -e "create database test"
    
Но это не сработало, вероятно, из-за кривости моих рук.
Поэтому был использован хитрый трюк: все запросы считывались из временного файла, в который предварительно записывались нужные команды :-)
Итак, приступим. Создаем файл create_db.bat и пишем в него следующее, далее разберем, что это вообще такое

    @echo off
    
    for /F %%d in (databases.txt) do (
        echo drop database if exists test_%%d;>temp_db.sql 
        echo create database test_%%d character set utf8 collate utf8_general_ci;>>temp_db.sql
        echo use test_%%d;>>temp_db.sql
        mysql -uroot -proot < temp_db.sql
        mysql -uroot -proot test_%%d < dump.sql
    )
    del temp_db.sql
    
    echo databases created
    @pause

Что тут понаписано.

1. @echo off
Отключаем вывод в консоль, мы будем выводить только то, что нам интересно
2. for /F %%d in (databases.txt) do (...)
Считываем построчно файл databases.txt, в котором находится список наших баз. Одна строка - одна база. Чтобы в названиях не было пробелов и разных загадочных символов, предлагаю позаботиться самим :-) Скобки нужны для выполнения серии команд
3. echo drop database if exists test_%%d;>temp_db.sql
Записываем в temp_db.sql команду удаления базы с таким названием, если она существует. Префикс test сделан для удобства. Обратите внимание, что переменная в цикле обозначается как %%d - сдвоенный процент и только один символ - таковы особенности. Если мы присваиваем переменные руками вне цикла, то можем использовать больше символов, а значение ее получать будем так %variable%
4. echo create database test_%%d character set utf8 collate utf8_general_ci;>>temp_db.sql
Создаем базу с кодировкой utf-8. Обратите внимание на > и >>. Первый оператор перезаписывает файл, второй добавляет текст в конец файла.
5. echo use test_%%d;>>temp_db.sql
Меняем текущую базу на только что созданную для последующего импорта в нее данных из dump.sql. Не забываем про ; в конце каждого запроса.
6. mysql -uroot -proot < temp_db.sql
Выполняем то, что мы сейчас закинули во временный файлик. Делаем это от пользователя, имеющего все необходимые права (создание-удаление баз и таблиц, вставка данных и прочее). Для упрощения сделаем это от рута
7. mysql -uroot -proot test_%%d < dump.sql
Загоняем данные в указанную базу из нашего дампа
8. del temp_db.sql
Вне цикла, удаляем уже ненужный временный файл
9. echo databases created
Выводим радостную надпись в консоль
10. @pause
Выводим приглашение нажать любую кнопку для выхода из консоли
11. profit

Потому как указанный батник мне приходилось запускать не один и даже не десять раз (для разного содержимого databases.txt), то удалять руками созданную кучу баз не хотелось. Поэтому написал еще один батник для удаления всего этого добра - destroy_db.bat.

    @echo off
    
    echo ;>temp_db.sql
    for /F %%d in (databases.txt) do (
        echo drop database if exists test_%%d;>>temp_db.sql
    )
    mysql -uroot -proot < temp_db.sql
    del temp_db.sql
    
    echo databases destroyed
    @pause

Здесь все по аналогии с предыдущим примером. Разница в том, что здесь мы в цикле записываем в файл команды для удаления баз, а потом выполняем только один раз. Так как в цикле мы записывали команды через добавление в конец файла >>, то перед циклом мы создали файл оператором > и записали в него пустую инструкцию ;

Очень надеюсь, что такую небольшую процедуру можно было сделать элегантнее и проще. Но особого времени разбираться с этим не было - мне просто нужно было наплодить кучу одинаковых баз и делать это много раз. Хотелось бы почитать комментарии умных людей на эту тему, но только когда я удосужусь подключить какой-нибудь Disqus к блогу :-)

Метки:
Заходите в группу в контакте - https://vk.com/webdevkin
Анонсы статей, обсуждения интернет-магазинов, vue, фронтенда, php, гита.
Истории из жизни айти и обсуждение кода.
Как Вам статья? Оцените!