В сети до сих пор висят мануалы из 2013, где предлагают писать громоздкие скрипты на PHP с библиотекой PHPExcel или использовать встроенный импорт через веб-интерфейс phpMyAdmin. На практике эти методы спотыкаются на первой же тысяче строк: слетают кодировки, ломаются форматы дат, а дробные числа округляются до целых.

При взаимодействии разработки с менеджментом или бухгалтерией регулярно всплывает одна и та же задача. Нужно либо выгрузить таблицу из базы в Эксель для отчёта, либо, наоборот, залить обратно в СУБД тяжелый xlsx. файл со свежими ценами или списком контрагентов. Настраивать тяжелые ETL-системы ради разовой выгрузки неэффективно. Проблема решилась написанием короткого CLI-скрипта на Python - mysql_bridge. Утилита обеспечивает сквозную двустороннюю конвертацию данных, автоматически анализирует структуру и сохраняет исходные типы на лету. Исходный код скрипта и Readme Здесь. Если Вас заинтересовала или статья была полезна, поддержите звездочками.

Как устроен двусторонний мост

Вся логика инструмента умещается за счёт связки pandas, sqlalchemy и движка openpyxl. Скрипт работает с файлами Эксель напрямую на уровне бинарного кода, поэтому его можно запускать на серверах без установленного офисного софта. Утилита работает в двух режимах.

  • Экспорт. Из MySQL в Excel

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

def export_to_excel(table_name, excel_path):

engine = create_engine(DATABASE_URL)

df = pd.read_sql_table(table_name, con=engine)

df.to_excel(excel_path, index=False, engine=‘openpyxl’)

  • Импорт. Из Excel в MySQL с автосозданием таблиц

Самая частая проблема ручного импорта - необходимость предварительно создавать пустую таблицу в MySQL через CREATE TABLE.

В разработанном мною скрипте этот процесс автоматизирован. Pandas предварительно сканирует Эксель-файл, определяет типы данных в памяти (строки, целые числа, вещественные числа, даты) и самостоятельно генерирует валидную таблицу в MySQL перед заливкой строк.

Флаг if_exists='replace' гарантирует, что если старая техническая таблица уже существовала в базе, она будет корректно пересоздана под новую структуру файла.

def import_from_excel(excel_path, table_name):

engine = create_engine(DATABASE_URL)

df = pd.read_excel(excel_path, engine=‘openpyxl’)

df.to_sql(table_name, con=engine, index=False, if_exists=‘replace’)

Тестирование и запуск в консоли

MySQL -> Excel

Перед запуском скрипта необходимо установить зависимости, выполнив команду

pip install pandas openpyxl sqlalchemy pymysql. Инструмент управляется через флаги, позволяя экспортировать данные из MySQL в Excel (--mode export) или импортировать обратно (--mode import), с автоматической обработкой типов данных и блокировок файлов. Рассмотрим на моём примере.

  • Открываем терминал в VS Code и ставим необходимые библиотеки:

    pip install pandas openpyxl sqlalchemy pymysql

  • После установки библиотек открываем код bridge.py и прописываем доступы к нашей бд в переменную DATABASE_URL. Тестирование проводилось на локальной базе medoiy_magazin.

  • Для проверки режима экспорта выгрузим существующую таблицу товаров products в файл Excel. Для этого в терминале запускается следующая команда с флагами:

    python bridge.py --mode export --table products --file products.xlsx

Таблица products в MySQL
Таблица products в MySQL
Она же, но уже в Эксель
Она же, но уже в Эксель
Терминал
Терминал

Excel -> MySQL

Для проверки обратного режима возьмем тестовый файл с новыми данными и зальем его в СУБД. Скрипт автоматически просканирует файл, определит типы колонок в памяти и сам создаст новую таблицу taste ,в нашей базе medoiy_magazin без предварительного написания SQL-запросов. Команда для импорта:

python bridge.py --mode import --file taste.xlsx --table taste.

Выгружаем таблицу Эксель в MySQL

Таблица в Эксель
Таблица в Эксель
Терминал
Терминал

Разработанный автономный инструмент оптимизирует обмен данными между СУБД и таблицами, предлагая CLI-решение для автоматизации отчетности и миграции без использования тяжелых ETL-систем. Утилита предназначена для регулярных выгрузок и интеграции в рабочие процессы, а код и документация открыты для комьюнити. Познакомьтесь с проектом на GitHub и поддержите его. Сюда

Комментарии (6)


  1. Akina
    01.07.2026 08:24

    Моё личное мнение - много лишнего. Уже ж гарантированно есть два достаточно мощных инструмента - MySQL и Excel, которых более чем достаточно для решения задачи, так какой великий смысл наворачивать ещё кучу инструментов (pandas, sqlalchemy и openpyxl)? Особенно если их (а то ещё и python до кучи) в системе изначально не имеется. Хотя надо-то всего лишь в Excel (вручную либо VBA-процедурой) пересохранить файл в CSV, или загрузить данные из того же формата, а с конвертацией в обе стороны (и созданием таблицы при необходимости) прекрасно справится достаточно несложная хранимая процедура на MySQL.


    1. laenij Автор
      01.07.2026 08:24

      Спасибо за взгляд из двухтысячных. Ручные манипуляции с CSV ломают структуру данных на первом же текстовом поле, где внутри ячейки окажутся обычные запятые или кавычки. Заставлять Linux-сервер бд тратить процессорное время на парсинг внутри хранимых процедур - значит положить СУБД при росте нагрузок. В 2026 году выполнить pip install и развернуть окружение на Python - это секундная задача для любого бэкендера, библиотеки весят копейки, а утилита работает автономно в фоне по cron без необходимости держать открытым графический интерфейс Excel для работы макросов. инструмент создан для нормальной автоматизации, чтобы инженеры не заставляли менеджеров вручную возиться с форматами. Мне кажется странным, экономить 20мб на легковесных библиотеках


      1. Akina
        01.07.2026 08:24

        Ручные манипуляции с CSV ломают структуру данных на первом же текстовом поле, где внутри ячейки окажутся обычные запятые или кавычки.

        Ну это заведомо неверное утверждение. Будь так - CSV не был бы стандартным средством переноса информации. Все текстовые поля (а при необходимости - вообще все поля) оборачиваются в кавычки, а кавычки внутри значения удваиваются либо экранируются - и никаких проблем ни с запятыми, ни с кавычками.

        Заставлять Linux-сервер бд тратить процессорное время на парсинг внутри хранимых процедур - значит положить СУБД при росте нагрузок.

        Описанная вами процедура - одноразовая. Это не однотипные запросы, которые летят от кучи клиентов большим и непредсказуемым потоком. Посему опасности "положить сервер" просто нет. Вот если бы импортировался, не приведи господи, XML, тогда да - процедура парсинга и импорта в MySQL тяжёлая и крайне по памяти прожорливая (кто импортировал ФИАС - знает).

        И учтите ещё один момент. Сервер БД специально приспособлен и оптимизирован для пакетной обработки данных, его собственно для этого и создавали. А уж по производительности и имеющимся ресурсам он вообще кроет клиента как бык овцу. К тому же передача одного CSV и передача набора записей - это несколько различающиеся нагрузки на сетевую подсистему.

        PS. К слову - а как ваш скрипт поведёт себя, если передаваемые данные содержат минорные форматные погрешности?


        1. laenij Автор
          01.07.2026 08:24

          Вы правы насчет стандартов в CSV, но на практике менеджеры присылают файлы из Excel, где ломаются переносы строк внутри ячеек, слетают длинные id в непонятный вид вроде 1E+11 или каверкаются даты. Из-за этого плоский формат требует постоянной ручной доработки. Процедура импорта действительно может быть разовой, но перекладывание логики парсинга файлов на сторону СУБД нарушает главный принцип разработки - разделение обязанностей. База должна быстро хранить и отдавать данные, а обрабатывать файлы должно легковесное приложение на Python, не забивая процессор MySQL лишней работой.

          Что касается мелких погрешностей в файле: под скриптом стоит библиотека pandas. Если в файле будут пропуски или мелкие косяки, скрипт не упадет, а просто автоматически заменит проблемные места на NaN и спокойно зальет таблицу дальше. Чтобы добиться такой же стабильности внутри хранимой процедуры на SQL, придется писать обработчик ошибок, который займет гораздо больше строчек, чем весь скрипт. В конце концов, это просто еще один готовый вариант автоматизации, который экономит время, и хуже от его наличия не будет.


          1. Akina
            01.07.2026 08:24

            Из-за этого плоский формат требует постоянной ручной доработки.

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

            Чтобы добиться такой же стабильности внутри хранимой процедуры на SQL, придется писать обработчик ошибок

            Это ещё зачем?

            просто автоматически заменит проблемные места на NaN и спокойно зальет таблицу дальше

            А вот это уже плохо. Получается, что скрипт по-тихому, никому не сообщая, сохраняет на сервере заведомо некорректные данные. ИМХО единственное правильное поведение в случае любой погрешности - это пропуск импорта проблемной записи с занесением её исходных данных в соотв. лог. Совсем хорошо - копирование "сырых" данных в специально предназначенную для этого таблицу. А если данные имеют внутренние ссылки, то процесс вообще должен быть остановлен до устранения выявленных проблем в исходных данных.


            1. laenij Автор
              01.07.2026 08:24

              Вы абсолютно правы, данные нельзя молча искажать в продакшене, но никакого сознательного умалчивания ошибок в коде нет: замена на NaN - это стандартное базовое поведение библиотеки Pandas при встрече с пустыми ячейками или некорректными форматами, и любой разработчик, использующий этот стек, знаком с такой логикой. Скрипт закрывает стандартную часть автоматизации рутины, и на практике никаких сбоев с типами данных при его работе не возникало. При этом никто не говорит, что автоматизация должна быть слепой панацеей, на которую нужно исключительно опираться - в любом случае финальные данные всегда можно подправить . Но наличие двух подходов в арсенале всегда лучше, чем один. Что касается идеи "надавать менеджеру по шее за халтуру" - всегда существует банальный человеческий фактор, кто-то где-то мог просто не доглядеть в файле, и это нормальный рабочий процесс. Я только учусь, развиваюсь в бэкенде, код открыт, поэтому любые подобные шероховатости с типами или логированием легко дорабатываются и исправляются в следующих коммитах. Это просто локальный, легковесный скрипт для отработки навыков и быстрой подстраховки