Download the PHP package timbrs/database-dumps without Composer

On this page you can find all versions of the php package timbrs/database-dumps. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package database-dumps

Database Dumps Package

[Tests]() [PHP Version]() [License]()

English


Русский язык

PHP-пакет для экспорта и импорта дампов баз данных в SQL. Поддерживает PostgreSQL, MySQL и Oracle (12c+). Работает с Symfony, Laravel и любым PHP-проектом.

Оглавление


Описание

Database Dumps — это PHP-пакет, который помогает разработчикам создавать и разворачивать дампы базы данных для локальной и тестовой среды.

Какую проблему решает? На проекте с большой боевой базой разработчику нужно иметь актуальные тестовые данные — но копировать всю базу долго, а персональные данные клиентов нельзя использовать в dev-окружении. Этот пакет позволяет настроить правила экспорта один раз: какие таблицы забирать целиком, какие — частично, и забыть о ручной подготовке дампов.

Как работает? Вы описываете в YAML-файле, какие таблицы и как экспортировать. Пакет сам:

Где применим? В любом PHP-проекте на Symfony или Laravel (или без фреймворка), где нужно:

Возможности

Установка

Быстрый запуск (LLM + OPENCODE)

Рекомендуемый, основной сценарий — анализ с участием ИИ. Пакет использует два источника:

Без настроенного LLM пакет тоже работает — анализ деградирует на regex-эвристики. Но рекомендуется именно LLM-сценарий.

Шаг 1. Сгенерировать конфиг (при первом запуске пакет сам спросит про LLM)

При первом запуске, если настройки LLM ещё не заданы, команда спросит:

  1. Настроить LLM сейчас? — да/нет (по умолчанию да);
  2. API URL — базовый адрес OpenAI-совместимого API (например https://gpt.example.com/v1);
  3. Модель — имя модели (по умолчанию openai/gpt-oss-120b);
  4. Token — Bearer-токен; можно оставить пустым (Enter).

Несекретные ответы (URL/модель) сохраняются в файл настроек — config/packages/database_dumps.yaml (Symfony) / config/database-dumps.php (Laravel), а Token — в .env.local (DBDUMP_LLM_TOKEN, при отсутствии — в .env); настройки применяются сразу в этом же запуске. Повторно спрашивать не будет. Если откажетесь — выбор тоже запомнится (анализ пойдёт на regex); включить позже — командой configure-llm (см. ниже).

ℹ️ Токен в файл настроек не пишется — он хранится в .env.local, поэтому файл настроек безопасно коммитить. В Symfony бандл регистрируется только вне prod.

Результат: dump_config.yaml (+ per-schema файлы) с автоопределёнными full_export/partial_export, секцией faker (LLM-детекция ПД) и каскадами по FK.

Шаг 2 (опционально). Обогатить конфиг анализом кода через OPENCODE

Нужен установленный opencode в PATH и настроенный в нём провайдер LLM (~/.config/opencode/opencode.json).

Команда сгенерирует в хост-проект всё необходимое для внешнего агента:

Документацию инструмента (рабочий цикл, команды, коды находок) генерирует app:dbdump:docs в docker/database/analysis/docs/ — она собирается из самого кода и потому не устаревает отдельно от него.

Команда собирает пакет и печатает, где он лежит; агента она не запускает — это делается снаружи (см. Анализ кода через OPENCODE). Результат агента (связи из кода → cascade_from: source: code, бизнес-сегменты → sample.criteria) применяет apply-analysis; отчёт — в {data_dir}/analysis/REPORT.md. Пользовательские правки в YAML в приоритете.

Шаг 3. Экспортировать и импортировать дампы

Переконфигурировать LLM в любой момент

Интерактивно меняет URL/модель/token, умеет проверить соединение и пересохранить настройки: несекретное — в файл настроек config/packages/database_dumps.yaml (Symfony) / config/database-dumps.php (Laravel), токен — в .env.local (DBDUMP_LLM_TOKEN).

Быстрый старт

Symfony

  1. Зарегистрируйте бандл вручную в config/bundles.php (Flex-рецепта нет):

  2. Создайте файл docker/database/dump_config.yaml (путь по умолчанию; переопределяется ключом config_path):

  3. Экспортируйте дампы:

  4. Импортируйте дампы:

Laravel

  1. Сервис-провайдер подключается автоматически. Файл docker/database/dump_config.yaml создаётся при первом запуске.

  2. Отредактируйте docker/database/dump_config.yaml (формат тот же, что и для Symfony).

  3. Экспортируйте дампы:

  4. Импортируйте дампы:

Конфигурация

Экспорт настраивается через YAML-файл. В нём две секции: full_export (все строки) и partial_export (с ограничениями).

Полный экспорт (full_export)

Экспортирует все строки из указанных таблиц:

Частичный экспорт (partial_export)

Экспортирует часть строк с фильтрацией:

Доступные опции:

Опция Описание
limit Максимум строк (для sample — общий потолок на объединённую выборку)
order_by Сортировка (должна заканчиваться на ASC или DESC)
where Условие WHERE
cascade_from Каскадная фильтрация по FK-родителю (см. ниже)
sample Выборка по именованным критериям («все фломастеры», см. ниже)

Каскадные зависимости (cascade_from)

При частичном экспорте связанных таблиц данные могут стать несогласованными: дочерняя таблица может ссылаться на строки, которые не попали в дамп родителя. Опция cascade_from решает эту проблему — она автоматически генерирует WHERE-подзапрос, ограничивающий выборку только теми строками, чей FK-родитель присутствует в дампе.

В этом примере:

Команда prepare-config автоматически определяет FK-зависимости и генерирует cascade_from. Чтобы отключить: --no-cascade.

Выборка по именованным критериям (sample)

Иногда нужно набрать «все фломастеры» — по 10–100 строк каждого бизнес-сегмента (красные/жёлтые/зелёные по статусу, новые/старые по дате, неактивные, VIP…), часто по разным колонкам и кросс-таблично. Опция sample задаёт набор именованных «корзин», каждая со своим WHERE и квотой; итоговая выборка — объединение всех корзин без дублей (дедуп по первичному ключу).

Как это работает:

Требования и поведение:

Вложенная и обратная стратификация

«Сто зелёных закрытых» — корзина на пару значений двух колонок, и «цвет клиента», который живёт не в clients, а в clients_attrs.value_string при attr_id = 4, — обе задачи решаются в той же секции sample:

Авто-генерация: с флагом --criteria (или --deep) prepare-config профилирует категориальные колонки и сам предлагает sample.criteria (по корзине на топ-значение). Бизнес-сегменты из кода (Eloquent scopes, методы репозиториев) добавляются через ветку OPENCODE — см. Углублённый анализ.

Замена персональных данных (faker)

Пакет может автоматически обнаруживать и заменять персональные данные при экспорте. Это позволяет безопасно использовать дампы в dev/staging окружениях.

Поддерживаемые паттерны:

Паттерн Описание Пример оригинала Пример замены
fio ФИО полностью Иванов Иван Иванович Петров Александр Сергеевич
fio_short ФИО сокращённо Иванов И.И. Козлов А.В.
name Фамилия Имя Иванов Иван Петров Александр
firstname Имя (кросс-корреляция с составной колонкой) Иван Александр
lastname Фамилия (кросс-корреляция с составной колонкой) Иванов Петров
patronymic Отчество (кросс-корреляция с составной колонкой) Иванович Сергеевич
email Email [email protected] [email protected]
phone Телефон +79161234567 +79234567890
gender Пол (12 форматов: male/female, м/ж, муж/жен и др.) Мужской Женский
inn ИНН (10 или 12 цифр, контрольные разряды пересчитаны) 7707083893 7712045619
ogrn ОГРН/ОГРНИП (13 или 15 цифр, контрольный разряд пересчитан) 1027700132195 1024306718432
digits Любой цифровой идентификатор с сохранением длины и разделителей (КПП, ОКПО, ОКАТО, ОКТМО, СНИЛС) 770701001 418362905
birth_date Дата рождения (сдвиг ±180 дней, формат исходной строки сохраняется) 1985-04-17 1985-09-02
doc_series Серия документа 4509 2731
doc_number Номер документа 123456 804517

Секция faker в конфигурации:

Паттерны firstname, lastname и patronymic детектируются через кросс-корреляцию: если в таблице уже найдена составная колонка (fio, fio_short, name), а рядом есть колонка с отдельными именами/фамилиями/отчествами — она будет обнаружена автоматически.

Паттерны inn, ogrn, digits, birth_date, doc_series и doc_number выводятся из значения: одинаковый вход даёт одинаковый выход в любой таблице и в любом прогоне. Иначе один и тот же ИНН превратился бы в clients в одно число, а в leads — в другое, и связь между записями в дампе разошлась бы. Длина, разделители и формат даты сохраняются, поэтому такой faker годится и для числовых колонок (bigint), и для date/timestamp.

Паттерн gender определяется по совпадению имени колонки (gender, sex, пол) и содержимого (допустимые значения: male/female, m/f, м/ж, мужской/женский, муж/жен, мужчина/женщина). Регистр и формат оригинала сохраняются при замене.

Команда prepare-config автоматически анализирует содержимое таблиц и генерирует секцию faker, если в колонках обнаруживаются паттерны ПД (порог совпадения: 80% из 200 случайных строк). Чтобы отключить: --no-faker.

Замена детерминирована — seed основан на хеше значения ФИО (колонка с паттерном fio), если такая колонка есть в конфигурации таблицы. Если колонки fio нет — seed берётся от хеша комбинации всех faker-значений строки. Это гарантирует, что одна и та же персона всегда получает одинаковую замену независимо от таблицы и запуска.

Разделение конфига по схемам (includes)

При большом количестве таблиц конфигурация может стать громоздкой. Команда prepare-config по умолчанию разбивает конфиг на отдельные файлы по схемам. Главный dump_config.yaml лежит в docker/database/, а пер-схемные файлы — в подкаталоге docker/database/dump-settings/:

Главный файл (docker/database/dump_config.yaml):

💡 Пути к include пишутся с префиксом ./ — так PhpStorm/IDE распознают их как ссылки на файлы: Ctrl+B / Cmd+B (или Ctrl+клик) на пути прыгает прямо в нужный *.yaml. На резолв путей загрузчиком префикс не влияет (работают оба варианта — с ./ и без).

Файл схемы (docker/database/dump-settings/public.yaml):

Чтобы генерировать единый файл без разделения: --no-split.

Несколько подключений

Если нужно работать с несколькими базами данных, добавьте секцию connections:

Куда сохраняются дампы:

data_dir — базовый каталог данных (по умолчанию docker/database), от него считается всё, что порождает пакет: главный конфиг ({data_dir}/dump_config.yaml), пер-схемные файлы ({data_dir}/dump-settings), дампы ({data_dir}/dumps), анализ ({data_dir}/analysis) и хуки ({data_dir}/before_exec, {data_dir}/after_exec). Изменить можно ключом data_dir в файле настроек — config/packages/database_dumps.yaml (Symfony) / config/database-dumps.php (Laravel) — или через env DBDUMP_DATA_DIR. В prod всегда используется дефолт docker/database.

Смена дефолта в 1.1.23. Раньше дефолтом был database, а путь к dump_config.yaml был зашит отдельной константой и не следовал за data_dir. Теперь дефолт — docker/database, и конфиг живёт внутри data_dir вместе с дампами. Установка, которая полагалась на прежний дефолт (ключ data_dir не задан), после обновления перестанет видеть свои файлы — пропишите data_dir: 'database' либо перенесите каталог.

Опция --connection:

Настройки (settings)

Секция settings позволяет изменять внутренние параметры пакета:

Автогенерация конфигурации

Команда prepare-config смотрит на структуру БД и создаёт или обновляет dump_config.yaml. Обязательный аргумент mode определяет область действия:

Режимы:

Режим Описание
all Полная регенерация конфигурации. Поверх существующего конфига отказывает — нужен --force
schema=<name> Перегенерация одной схемы, мёрж в существующий конфиг
table=<schema.table> Перегенерация одной таблицы, мёрж в существующий конфиг
new Обнаружение и дописывание новых таблиц (не затрагивает существующие)

Режим all собирает конфиг заново и существующий файл не читает: настроенные вручную sample.criteria, cascade_from, limit и faker он заменяет машинной догадкой. Поэтому при существующем dump_config.yaml команда отказывается работать и называет режимы, которые мёржат, а не затирают (new, schema=, table=), а также check-criteria и validate. Осознанная пересборка с нуля — prepare-config all --force.

Опции:

Опция Описание По умолчанию
--threshold, -t Порог строк: таблицы с количеством строк <= порога идут в full_export, больше — в partial_export 500
--force, -f Разрешить полную регенерацию поверх существующего конфига (только для режима all) —
--no-cascade Пропустить обнаружение FK и генерацию cascade_from —
--no-faker Пропустить обнаружение персональных данных —
--no-split Генерировать единый YAML без разделения по схемам —
--criteria Авто-генерация sample.criteria из категориальных колонок —
--ai / --no-ai Включить/отключить LLM-детекцию ПД (авто: включается, если LLM настроен — env DBDUMP_LLM_URL или файл настроек). --no-ai также подавляет авто-запрос настройки LLM при первом запуске авто
--deep Глубокий анализ: профилирование + ИИ + sample.criteria + отчёт docker/database/analysis/REPORT.md —

Как распределяются таблицы:

Углублённый анализ (--deep / --ai / --criteria)

Анализ с участием ИИ — основной сценарий пакета. Опирается на два источника:

Если LLM не настроен, анализ мягко деградирует на regex-эвристики — пакет остаётся работоспособным. См. также Быстрый запуск.

Настройка LLM (интерактивно)

При первом запуске prepare-config (если настройки LLM ещё не заданы и сессия интерактивна) пакет сам предложит настроить LLM — спросит API URL, Модель и Token (token можно оставить пустым), сохранит несекретное в файл настроек, токен — в .env.local (DBDUMP_LLM_TOKEN), и применит настройки немедленно в этом же запуске. Отказ тоже запоминается, чтобы не спрашивать снова. Авто-запрос подавляется флагом --no-ai и в неинтерактивном режиме (--no-interaction, CI).

Настроить или изменить LLM в любой момент можно явной командой — она дополнительно умеет проверить соединение:

После настройки --ai/--deep и prepare-analysis подхватывают параметры автоматически. Приоритет источников: переменные окружения DBDUMP_LLM_* (если задан URL) перекрывают файл настроек config/packages/database_dumps.yaml (Symfony) / config/database-dumps.php (Laravel); токен всегда берётся из окружения (.env.local → .env) и в файл настроек не пишется.

LLM-детекция ПД и профилирование

Переменные окружения LLM:

Переменная Назначение По умолчанию
DBDUMP_LLM_URL Базовый URL OpenAI-совместимого API (например https://llm.example.com/v1). Пусто → AI-функции выключены —
DBDUMP_LLM_MODEL Имя модели openai/gpt-oss-120b
DBDUMP_LLM_TOKEN Bearer-токен (опционально) —
DBDUMP_LLM_TIMEOUT Таймаут запроса, сек 120
DBDUMP_LLM_ENABLED true/false; по умолчанию авто (включено при заданном URL) авто

HTTP-запросы выполняются через ext-curl (без guzzle). Данные PII в промптах ограничены примерами значений колонок.

Анализ кода через OPENCODE

Пакет не запускает агента. До 1.1.26 prepare-analysis --run дёргал opencode через exec() из PHP — и это оказалось неверным слоем. Агент сам решает, чем и в каком порядке пользоваться, и умеет вызвать prepare-analysis, validate и check-criteria куда осмысленнее, чем PHP умеет вызвать агента. За пакетом осталась детерминированная часть: собрать факты (инвентарь схемы, находки валидатора, падающие criteria с ошибкой СУБД) и применить готовый результат (apply-analysis). Решения — эвристики, починка, выбор режима выгрузки — снаружи. В пакете не осталось ни одного вызова внешнего процесса.

Самый простой путь — одной командой (нужен opencode в PATH):

Команда собирает пакет (инвентарь схемы, пер-схемные инвентари, контракт вывода) и печатает, где он лежит. Прогон агента — снаружи; применение результата — apply-analysis.

Ручной путь (3 шага) — если хотите контролировать прогон агента:

Что провижинит prepare-analysis в хост-проект:

Решения (decisions.<schema>.json)

Правила читают досье и предлагают правки. Тулза применяет сама только механическое — записи с auto: true:

правило о чём авто
R1 полная выгрузка таблицы крупнее порога → частичная с order_by и разрезами нет
R2 словарь, маленькая таблица, таблица с высокой входящей степенью или наполняемая миграцией → выгружать целиком нет
R3 категориальная колонка без покрытия → корзины (stratify; для EAV — attr_id + вложенный value_*) нет
R4 колонка с ПД-именем без faker → маскировать да
R5 связь без cascade_from да для внешнего ключа БД
R6 SCD2-таблица без разрезов → три критерия: текущая активная, деактивированная, история нет
R7 таблица в конфиге, которой нет в БД → удалить да
R8 кандидат в корзины с более чем 50 различными значениями → нужны критерии по группам нет
R9 case enum'а из кода не встречается в БД (и наоборот) нет
R10 квота × число корзин больше limit → снизить квоту нет
R11 phone/fio на числовой или датной колонке → inn/digits/birth_date да

Значений данных в решениях нет: только имена таблиц, колонок и case'ов enum'ов. id записи считается от адреса и предложения, поэтому отметка accepted переживает повторный analyze, а изменившееся предложение придётся принимать заново.

Изменено в 1.1.32. Пакет больше не кладёт .opencode/agents/dbdump-mapper.md, .opencode/commands/dbdump-map.md и analysis/RUN.md: инструкция устаревала отдельно от кода. Её место заняли app:dbdump:docs (документация из самого инструмента) и политика запуска агента в проекте.

Применение: apply

Записывает решения в dump_config.yaml. Три правила, которые не обойти:

Предложение проверяется через TableConfig::fromArray() до мутации, поэтому битая запись не оставляет конфиг полуприменённым. Итог с провенансом (правило, обоснование, доказательства, статус) — в docker/database/analysis/apply-report.json; изменённый YAML пишется только если хоть одно решение применилось.

Старый вывод агента (analysis/out/*.json) тот же вызов применяет по-прежнему: cascade_from из кода и sample.criteria из бизнес-сегментов, пользовательские правки в приоритете, провенанс в docker/database/analysis/REPORT.md. Кроме того, prepare-analysis показывает его в новом виде — связи и сегменты как решения с rule: legacy (всегда требуют отметки), а columns[] как заметки агента в досье: раньше они просто выбрасывались.

Для больших схем дробите прогон по чанку на схему — пер-схемные инвентари для того и пишутся.

Одна команда проверки: check

check прогоняет все проверки и складывает находки в одно пространство кодов. Стадии выбираются по тому, что доступно, и каждая честно докладывает, почему пропущена:

стадия что проверяет что нужно
static конфиг против слепка схемы (коды S/C/L/Q-1…Q-5/F/G/D/H); --fix чинит однозначное слепок
live каждый sample.criterion в БД под statement_timeout: Q-7 падает, Q-8 таймаут, Q-6 корзина пуста; P-1/P-2 из слепка живая БД
plan что и как будет выгружено: режим, where, каскад, корзины ничего
dump что реально легло в dumps/: V-1…V-8 файлы дампа
import контрольная заливка в scratch-БД: I-1…I-4 --import-connection

Опции: --stage (повторяемая; по умолчанию все, кроме plan), -s|--schema, --tables-from (файл со списком schema.table или dirty.json), --config, --inventory, -c|--connection, --import-connection, --fail-on=error|warning|note (порог кода возврата 1), --fix, --format=text|json, --out.

Отчёт — один JSON: {generated_at, run_id, stages:{ran, why_skipped, ms, queries, …}, summary, coverage, findings[]}, у каждой находки есть stage. Узкие команды validate, check-criteria и verify-dump остаются рабочими: это подмножества check с прежними опциями.

Документация из инструмента: docs

docs пишет четыре файла: WORKFLOW.md (рабочий цикл), DOSSIER.md (что лежит в dossier.<schema>.json и что означают пометки ambiguous), COMMANDS.md (собран из определений команд — те же опции, что в --help), FINDINGS.md (реестр кодов: стадия, уровень, смысл, чинится ли --fix, кто решает). Это же кладут в проект для агента, чтобы он не гадал по устаревшему мануалу.

Паритет мостов Symfony и Laravel

Ядро пакета общее, различаются только консольные мосты. Восемь исходных команд работают в обоих; новые — только Symfony, и Laravel-мост заморожен: новые зависимости в нём nullable, код PHP 7.2-совместимый.

команда Symfony Laravel
prepare-config, prepare-analysis, apply-analysis, validate, check-criteria/repair-configs, export, import, db-init да да
check (стадии static/live/plan/dump/import) да нет
checkpoint, --since-checkpoint, --since-migration да нет
docs, app:dbdump (рабочий цикл) да нет
verify-dump да нет
алиас apply, опции -s/--decisions/--legacy у apply-analysis да нет

Laravel-команда dbdump:apply-analysis применяет только старый вывод агента (analysis/out/*.json); решения decisions.<schema>.json читает Symfony-мост.

Инкремент: checkpoint и грязный набор

Первый прогон — полный, дальше перепроверять всё незачем. Отметка docker/database/analysis/checkpoint.json хранит самую новую миграцию, время слепка, коммит и хеши по каждой таблице: настройки, состав колонок, набор кодов, внешние ключи. Времени мало — конфиг могли поправить и вернуть, а в базе за неделю мог появиться новый status_id без единой миграции; хеш это ловит, время нет.

Четыре сенсора:

сенсор что ловит почему отдельно
миграции версии новее отметки, с их DDL и наполнением колонка появляется миграцией — основной путь изменений
конфиг хеш настроек таблицы (порядок ключей не считается) правку YAML руками не увидит никто другой
слепок columns, codes+distinct_count, внешние ключи новое значение status_id приходит без миграции
git файлы миграций, изменившиеся после коммита отметки ловит откаты и правки уже применённых миграций

Результат — docker/database/analysis/dirty.json с причиной по каждой таблице; он подаётся дальше как есть (check --tables-from=…/dirty.json), а --since-checkpoint делает то же одним флагом. Отдельно в отчёте видно таблицы, которые миграция завела, а конфиг не знает (повод дозапустить prepare-config), и те, что исчезли из конфига после отметки.

Границы честности сенсоров. На схлопнутой истории (clone --depth=1, а в закрытом контуре это норма) git diff по старому коммиту невозможен: сенсор докладывает, что отключён, и работают остальные три — молча объявлять всё чистым он не станет. Слепок сравнивается тем же кодом, что считает хеши для новой отметки, поэтому расхождение формул не превратится в вечно грязный набор. Отметки нет — грязное всё, и это значит «нужен полный цикл», а не «изменений не найдено».

--save — отдельный флаг: случайно перезаписать отметку нельзя, а посмотреть грязный набор можно в любой момент.

Проверка конфига без БД (validate)

validate проверяет dump_config.yaml и пер-схемные dump-settings/*.yaml, не подключаясь к базе. Схему берёт из замороженного слепка {data_dir}/analysis/schema_inventory.json (и пер-схемных schema_inventory.<schema>.json), который кладёт prepare-analysis. Поэтому команда работает в CI, в закрытом контуре и до подъёма стенда — в отличие от check-criteria, который гоняет каждый criterion по живой БД.

Опции: --config и --inventory (пути, по умолчанию — {data_dir}/dump_config.yaml и {data_dir}/analysis/schema_inventory.json), -s|--schema (повторяемая, только эти схемы), --format=text|json, --out=PATH, --severity=error|warning|note (порог вывода), --fix (применить механически однозначные правки).

Код возврата — 1, если есть находки уровня error, иначе 0. Этого достаточно, чтобы скрипт или агент решил «готов конфиг к снятию дампа или нет», не разбирая текст вывода.

Что проверяется

код уровень что нашли
S-1 error YAML не разобрался или файл из includes: пропал
S-2 error TableConfig отверг настройки таблицы
S-3 error таблица и в full_export, и в partial_export
S-4 warning пустая секция / пустая карта faker у таблицы
C-1 warning таблица есть в слепке, но не выгружается
C-2 warning таблица есть в конфиге, но её нет в слепке
C-3 warning схема есть на одной стороне и отсутствует на другой
L-1…L-7 error / warning несуществующие колонки в order_by, where, cascade_from, sample.criteria, stratify_by, faker, deferred_columns
Q-1, Q-2 error в критерии алиас таблицы (t1.) или bind-параметр (:name) — дампер такой критерий пропустит
Q-3 error непригодны ВСЕ критерии таблицы: выборка молча выродится в плоский срез
Q-4 warning повторяющиеся имена критериев
Q-5 warning сумма квот больше limit — объединённую выборку молча обрежет
F-1 error / warning faker-паттерн на нетекстовой колонке: на дате/bytea/uuid INSERT упадёт (error), на числовой — подменит идентификатор (warning)
F-2 error паттерн вне PatternDetector::ALLOWED_PATTERNS — FakerConfig не примет конфиг
G-1 error родитель cascade_from не выгружается — ограничение молча отбросится
G-2 error цикл в cascade_from
G-3 warning цепочка длиннее settings.max_cascade_depth
G-4 warning родитель с sample выгружается ПОЗЖЕ ребёнка
G-5 note родитель с sample выгружается раньше — связность держится на порядке имён
G-6 note у таблицы и sample, и cascade_from: cascade не применится
D-1 note справочник *_dict обрезан лимитом или квотами
H-1 note версионная таблица (date_from/date_to) выбирает только действующие версии

G-4 заслуживает отдельного слова. Порядок экспорта строит TopologicalSorter по FK из слепка; в базе без FK-констрейнтов рёбер нет вовсе, и порядок вырождается в алфавитный. Тогда родитель, чьё имя идёт позже имени ребёнка, попадает в дамп уже после него, реестр выбранных id (SelectedPkRegistry) пуст, и CascadeWhereResolver откатывается к подзапросу, который не повторяет sample.criteria — набор строк родителя в дампе и в подзапросе расходится.

Что делает --fix

Только то, где правка однозначна и не меняет состав выборки: снимает faker-маппинг с нетекстовой колонки (F-1) и с неизвестным паттерном (F-2), убирает маппинг несуществующей колонки (L-6) и мёртвую запись cascade_from (L-3), переименовывает дубль критерия (Q-4), удаляет пустую секцию (S-4). Всё остальное остаётся находкой с подсказкой — решение за человеком.

Правки пишутся в тот файл, откуда пришла схема (dump-settings/<schema>.yaml или общий конфиг); тронутый файл переписывается целиком, поэтому его форматирование становится каноническим (записи cascade_from разворачиваются из однострочной формы в блочную). Файлы, где чинить нечего, не трогаются. После правок содержимое перепроверяется тем же TableConfig, что и на экспорте: если правка сделала конфиг хуже, файл не записывается.

Проверяется только основное подключение; секция connections: в аудит не входит.

Проверка выгруженных дампов (verify-dump) и отчёт импорта

verify-dump смотрит на то, что реально легло в {data_dir}/dumps/, — validate и check-criteria туда не заглядывают. К БД не подключается; каждый файл читается один раз для всех проверок, наружу уходят только счётчики и имена колонок — значений данных в отчёте нет.

Опции: -s|--schema, -c|--connection, --inventory (слепок схемы, по умолчанию {data_dir}/analysis/schema_inventory.json; без слепка проверки по нему пропускаются с пометкой в отчёте), --format=text|json, --out=PATH. Код возврата — 1 при ошибках.

код уровень что нашли
V-1 error строки ребёнка ссылаются на родителя, которого нет в выгрузке, — каскад не ограничил выборку; для ребра по FK из БД: импорт с констрейнтом такой дамп не примет
V-2 warning таблица есть в конфиге, файла дампа нет
V-3 warning родитель связи не выгружен (или FK ссылается на таблицу вне конфига) — сверять нечем
V-4 error колонки связи нет в дампе
V-5 warning покрытие значений: кодов/категорий колонки в дампе меньше, чем в слепке; в подсказке — какие коды отсутствуют (codes из pg_stats — только частые значения, поэтому не error)
V-7 error / warning колонка без faker, а значения выглядят как e-mail, телефон или ФИО (error); имя колонки говорит о ПД, а значений для проверки по содержимому мало (warning)
V-8 error / warning строк больше limit или суммы квот sample.criteria (error); full_export расходится со слепком (с допуском 10 %, если размер там — оценка) или дамп пуст при непустой таблице (warning)

Рёбра для V-1 — объединение cascade_from и внешних ключей из слепка (foreign_keys): сегодня в базе без констрейнтов второй список пуст, но появись FK — связь проверяется без правки конфига.

import возвращает отчёт с теми же правилами игры: ошибки в нём дают код возврата 1, даже если транзакция прошла; --out=PATH пишет отчёт в JSON.

код уровень что нашли
I-1 error таблица пропущена: колонки дампа расходятся со схемой БД (с --ignore-schema-mismatch — warning, таблица залита)
I-2 error после заливки в таблице не столько строк, сколько в файле дампа
I-3 warning sequence отстаёт от максимума колонки (PostgreSQL) — первый INSERT приложения упрётся в дубликат ключа
I-4 error внешний ключ нарушен — в дампе строки без родителя; отложенные констрейнты проверяются SET CONSTRAINTS ALL IMMEDIATE внутри транзакции

Настройка Symfony

Регистрация бандла

Flex-рецепта у пакета нет, поэтому бандл нужно зарегистрировать вручную. Добавьте в config/bundles.php:

Регистрация в dev/test соответствует установке через composer require --dev. Если пакет ставится в prod (без --dev), регистрируйте бандл как ['all' => true].

Настройки бандла

Все настройки живут в одном файле config/packages/database_dumps.yaml под корневым ключом database_dumps:. Файл необязателен — без него работают дефолты.

⚠️ Если бандл зарегистрирован как ['dev' => true, 'test' => true] (рекомендованный вариант выше), секцию ОБЯЗАТЕЛЬНО оборачивать в when@dev: / when@test:. Файлы config/packages/*.yaml грузятся во всех окружениях, а расширения database_dumps в prod нет — голый корневой ключ уронит сборку контейнера: There is no extension able to load the configuration for "database_dumps". Так же устроены штатные web_profiler.yaml и debug.yaml. При регистрации ['all' => true] обёртка не нужна.

Полный список ключей (здесь без обёртки, для случая ['all' => true]):

jobs больше не служебная (1.1.34). Раньше это имя было в жёстком списке, и вместе с очередью Laravel из инвентаря молча пропадала бизнес-таблица с тем же именем. Очередь по-прежнему ловится по failed_jobs/job_batches; если в вашем проекте jobs — это действительно очередь, добавьте её в service_tables.exact. Указанный ключ заменяет умолчание целиком, а не дополняет его: перечисляйте полный список.

Токен сюда не кладётся. Он живёт в .env.local (DBDUMP_LLM_TOKEN), поэтому файл безопасно коммитить. Переменные окружения DBDUMP_* перекрывают значения из этого файла. Работают и оверрайды по окружениям — config/packages/dev/database_dumps.yaml.

Переезд конфига в 1.1.24. Раньше data_dir, llm и opencode лежали отдельным PHP-файлом config/database-dumps.php, а бандл читал его в обход DI. Теперь это обычный конфиг бандла. При обновлении перенесите значения из старого файла в config/packages/database_dumps.yaml под ключ database_dumps: и удалите старый — Symfony-бридж его больше не читает. В Laravel формат не изменился: там по-прежнему публикуемый config/database-dumps.php.

Бережный доступ к БД (db)

Разведка (prepare-config, prepare-analysis, check-criteria) работает и на боевой базе, поэтому пакет не читает данные там, где хватает статистики планировщика, и ограничивает всё остальное. В Laravel те же ключи — секция db в config/database-dumps.php (env DBDUMP_DB_*).

Инвентарь получает row_count_estimated, row_count_source и список warnings (P-1/P-2).

pgbouncer в режиме transaction pooling не сохраняет сессионный SET между транзакциями — задайте таймауты на стороне пула.

Структура каталогов (Symfony)

Команды Symfony

Настройка Laravel

Регистрация провайдера

Сервис-провайдер подключается автоматически. Если нет — зарегистрируйте в config/app.php:

Публикация конфигурации

Чтобы изменить пути, опубликуйте PHP-конфигурацию:

Появится файл config/database-dumps.php:

Команды Laravel

Скрипты before/after

Можно выполнять свои SQL-скрипты до и после импорта.

Каталог Когда выполняется
docker/database/before_exec/ до импорта дампов
docker/database/after_exec/ после импорта дампов

Скрипты выполняются в алфавитном порядке. Используйте числовые префиксы для управления очерёдностью:

Чтобы пропустить скрипты, используйте --skip-before и --skip-after:

Поддержка IDE (JSON Schema)

В пакете есть JSON Schema для dump_config.yaml — файл resources/dump_config.schema.json. Он даёт автодополнение и валидацию в PHPStorm и других IDE.

Вариант 1: YAML-комментарий (рекомендуется)

Добавьте в начало dump_config.yaml:

Путь указывается относительно файла: для Symfony — относительно config/, для Laravel — относительно docker/database/.

Вариант 2: Настройка PHPStorm вручную

  1. Откройте Settings > Languages & Frameworks > Schemas and DTDs > JSON Schema Mappings
  2. Добавьте маппинг:
    • Schema file: vendor/timbrs/database-dumps/resources/dump_config.schema.json
    • File path pattern: dump_config.yaml

Архитектура

Как работает экспорт

  1. TableConfigResolver — читает YAML и собирает список таблиц для экспорта
  2. DatabaseDumper — управляет процессом экспорта
  3. TableDependencyResolver — топологическая сортировка таблиц по FK (родители экспортируются первыми). При обнаружении циклов — автоматический разрыв через nullable-рёбра
  4. DataFetcher — получает данные из БД через ConnectionRegistry
  5. CascadeWhereResolver — генерирует WHERE-подзапросы из cascade_from для связности данных
  6. RussianFaker — заменяет персональные данные (ФИО, email, телефон, пол) на сгенерированные
  7. SqlGenerator — генерирует SQL: TRUNCATE + INSERT (с NULL для разорванных FK) + сброс счётчиков + UPDATE (восстановление FK)
  8. Результат сохраняется в docker/database/dumps/{schema}/{table}.sql

Как работает импорт

  1. ProductionGuard — проверяет, что мы не на продакшене
  2. TransactionManager — оборачивает всё в транзакцию
  3. TableDependencyResolver — топологическая сортировка файлов по FK (родители импортируются первыми), с автоматическим разрывом циклов
  4. SchemaValidator — сравнивает столбцы дампа со столбцами в БД, предупреждает о расхождениях
  5. ScriptExecutor — выполняет скрипты из before_exec/
  6. SqlParser / StatementSplitter — разбирает .sql файлы на отдельные выражения
  7. Выражения выполняются в БД
  8. ScriptExecutor — выполняет скрипты из after_exec/

Различия платформ

Пакет сам генерирует правильный SQL в зависимости от СУБД:

PostgreSQL MySQL Oracle (12c+)
Имена таблиц "table" (двойные кавычки) `table` (обратные кавычки) | "TABLE" (двойные кавычки, UPPERCASE)
TRUNCATE TRUNCATE ... CASCADE SET FOREIGN_KEY_CHECKS=0 DELETE FROM (FK-safe)
Счётчики setval() / pg_get_serial_sequence() ALTER TABLE ... AUTO_INCREMENT Комментарий-заглушка (используйте after_exec/)
LIMIT LIMIT N LIMIT N FETCH FIRST N ROWS ONLY
INSERT Батч 1000 строк Батч 1000 строк По одной строке (нет multi-row INSERT)
Случайное число RANDOM() RAND() DBMS_RANDOM.VALUE

Платформа определяется автоматически по подключению к БД.

Oracle: используется DELETE FROM вместо TRUNCATE TABLE, т.к. Oracle TRUNCATE не поддерживает CASCADE и блокируется FK constraints. Сброс sequences требует PL/SQL — используйте скрипты в docker/database/after_exec/.

Структура исходного кода

Безопасность

Пакет не позволяет случайно импортировать дампы на продакшен. Импорт заблокирован, когда переменная окружения APP_ENV равна prod или predprod.

Тестирование

Полный цикл на живой БД

tests/Integration/FullCycleTest.php прогоняет цепочку целиком: сид → слепок → досье → решения → apply → check (static/live/plan) → export → check --stage=dump. Юнит-тесты проверяют каждое звено с моками, а расходятся звенья как раз на стыках — на форме слепка, на том, что решение адресует таблицу так же, как её называет конфиг, на порядке выгрузки. Без живой базы такой стык не проверить.

Без DBDUMP_TEST_DSN тест пропускается — в закрытом контуре базы в CI нет:

Тест работает в своей схеме (dbdump_it), которую сам создаёт и сносит в tearDown — чужие таблицы не трогает. Подойдёт любой Postgres, в том числе поднятый локальным стендом хост-проекта (docker-compose.local.yml, сервис postgres).

Локальная разработка

Чтобы подключить пакет из локальной папки (без Packagist), добавьте в composer.json вашего проекта:

Затем выполните composer update timbrs/database-dumps — Composer создаст симлинк на локальный пакет.

Требования

Обязательные:

Нижняя планка — 7.1: пакет ставится в том числе в проекты, которые с неё не сдвинулись. На практике нужен 7.1.3 — столько требует Symfony 4.4, самая старая поддерживаемая ветка symfony/yaml и symfony/finder.

Совместимость проверяется не на глаз, а сниффами:

(PHPCompatibility по src/ с testVersion 7.1-). Это единственный способ поймать, например, array_key_first() или флаг JSON_INVALID_UTF8_SUBSTITUTE — оба появились после 7.1 и оба уже пробирались в код. Тесты и статический анализ такого не видят: они гоняются на современном PHP.

Опциональные (зависят от фреймворка):

Зависимость Для чего нужна
doctrine/dbal ^2.13 | ^3.0 | ^4.0 Адаптер Doctrine DBAL (Symfony)
symfony/console ^4.4 | ^5.4 | ^6.0 | ^7.0 Консольные команды Symfony
symfony/http-kernel ^5.4 | ^6.0 | ^7.0 Регистрация бандла Symfony
illuminate/support ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 Сервис-провайдер Laravel
illuminate/console ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 Artisan-команды Laravel
illuminate/database ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 Адаптер БД Laravel

Лицензия

MIT License. Подробнее в файле LICENSE.


English

PHP package for exporting and importing database dumps as SQL. Supports PostgreSQL, MySQL, and Oracle (12c+). Works with Symfony, Laravel, and any PHP project.

Table of Contents


Description

Database Dumps is a PHP package that helps developers create and deploy database dumps for local and test environments.

What problem does it solve? On a project with a large production database, developers need up-to-date test data — but copying the entire database is slow, and using real customer data in dev environments is not acceptable. This package lets you configure export rules once — which tables to grab in full, which partially — and forget about manual dump preparation.

How does it work? You describe export rules in a YAML file. The package then:

Where is it useful? In any PHP project using Symfony or Laravel (or standalone), where you need to:

Features

Installation

Quick Start

Symfony

  1. Register the bundle manually in config/bundles.php (there is no Flex recipe):

  2. Create docker/database/dump_config.yaml (default path; override via config_path):

  3. Export dumps:

  4. Import dumps:

Laravel

  1. The service provider is discovered automatically. The file docker/database/dump_config.yaml is created on first run.

  2. Edit docker/database/dump_config.yaml (same format as Symfony).

  3. Export dumps:

  4. Import dumps:

Configuration

Export is configured via a YAML file with two sections: full_export (all rows) and partial_export (with limits).

Full Export

Exports all rows from listed tables:

Partial Export

Exports a limited number of rows with filtering:

Available options:

Option Description
limit Max rows
order_by Sorting (must end with ASC or DESC)
where WHERE condition
cascade_from Cascade filtering by FK parent (see below)

Cascade Dependencies (cascade_from)

When partially exporting related tables, data can become inconsistent: a child table may reference rows that didn't make it into the parent's dump. The cascade_from option solves this by automatically generating a WHERE subquery that limits the selection to only those rows whose FK parent is present in the dump.

In this example:

The prepare-config command automatically detects FK dependencies and generates cascade_from. To disable: --no-cascade.

Personal Data Masking (faker)

The package can automatically detect and replace personal data during export. This allows safe use of dumps in dev/staging environments.

Supported patterns:

Pattern Description Original example Replacement example
fio Full Russian name Иванов Иван Иванович Петров Александр Сергеевич
fio_short Short Russian name Иванов И.И. Козлов А.В.
name First and last name Иванов Иван Петров Александр
firstname First name (cross-correlated with composite column) Иван Александр
lastname Last name (cross-correlated with composite column) Иванов Петров
patronymic Patronymic (cross-correlated with composite column) Иванович Сергеевич
email Email address [email protected] [email protected]
phone Phone number +79161234567 +79234567890
gender Gender (12 formats: male/female, m/f, м/ж, etc.) Мужской Женский
inn Russian tax number (10 or 12 digits, checksum recomputed) 7707083893 7712045619
ogrn Russian state registration number (13 or 15 digits) 1027700132195 1024306718432
digits Any numeric identifier, length and separators preserved (KPP, OKPO, OKATO, OKTMO, SNILS) 770701001 418362905
birth_date Birth date (shifted by ±180 days, original format preserved) 1985-04-17 1985-09-02
doc_series Document series 4509 2731
doc_number Document number 123456 804517

The faker section in configuration:

The inn, ogrn, digits, birth_date, doc_series and doc_number patterns are value-seeded: the same input always produces the same output, in every table and every run. Otherwise one tax number would map to different values in clients and in leads, breaking the link between records in the dump. Length, separators and date format are preserved, so these patterns also fit numeric (bigint) and date/timestamp columns.

The firstname, lastname, and patronymic patterns are detected via cross-correlation: if a composite column (fio, fio_short, name) is already found in the table and there's an adjacent column with individual first names/last names/patronymics — it will be detected automatically.

The gender pattern is detected by matching both the column name (gender, sex, пол) and its contents (valid values: male/female, m/f, м/ж, мужской/женский, муж/жен, мужчина/женщина). The original value's case and format are preserved during replacement.

The prepare-config command automatically analyzes table contents and generates the faker section when PII patterns are detected in columns (threshold: 80% match from 200 random rows). To disable: --no-faker.

Replacement is deterministic — the seed is based on the hash of the FIO value (column with fio pattern), if such a column exists in the table's faker config. If there is no fio column, the seed is computed from the hash of all faker column values in the row. This ensures the same person always gets the same replacement regardless of the table or run.

Config Splitting by Schema (includes)

When dealing with many tables, the configuration can become unwieldy. The prepare-config command splits config into per-schema files by default. The main dump_config.yaml lives in docker/database/, and per-schema files go into the docker/database/dump-settings/ subdirectory:

Main file (docker/database/dump_config.yaml):

💡 Include paths are written with a ./ prefix so PhpStorm/IDEs treat them as file references: Ctrl+B / Cmd+B (or Ctrl+click) on a path jumps straight to the target *.yaml. The prefix does not affect path resolution (both ./-prefixed and plain relative paths load fine).

Schema file (docker/database/dump-settings/public.yaml):

To generate a single file without splitting: --no-split.

Multiple Connections

To work with several databases, add a connections section:

Where dumps are saved:

data_dir is the base data directory (default docker/database). Everything the package produces is resolved from it: the main config ({data_dir}/dump_config.yaml), per-schema files ({data_dir}/dump-settings), dumps ({data_dir}/dumps), analysis ({data_dir}/analysis) and hooks ({data_dir}/before_exec, {data_dir}/after_exec). Change it in the data_dir key of the settings file — config/packages/database_dumps.yaml (Symfony) / config/database-dumps.php (Laravel) — or via the DBDUMP_DATA_DIR env var. In prod the default docker/database is always used.

Default changed in 1.1.23. It used to be database, and the path to dump_config.yaml was a separate hardcoded constant that did not follow data_dir. The default is now docker/database, and the config lives inside data_dir next to the dumps. An installation that relied on the old default (no data_dir key set) will stop seeing its files after the upgrade — set data_dir: 'database' or move the directory.

The --connection option:

Settings

The settings section allows you to customize internal package parameters:

Auto-generate Configuration

The prepare-config command looks at your DB structure and creates or updates dump_config.yaml. The required mode argument defines the scope:

Modes:

Mode Description
all Full config regeneration. Refuses over an existing config — --force required
schema=<name> Regenerate one schema, merge into existing config
table=<schema.table> Regenerate one table, merge into existing config
new Detect and append new tables only (doesn't touch existing entries)

all mode rebuilds the config from scratch and never reads the existing file: hand-tuned sample.criteria, cascade_from, limit and faker are replaced by machine guesses. That is why the command refuses to run over an existing dump_config.yaml and points at the modes that merge instead of overwriting (new, schema=, table=), plus check-criteria and validate. A deliberate rebuild from scratch is prepare-config all --force.

Options:

Option Description Default
--threshold, -t Row threshold: tables with rows <= threshold go to full_export, more — to partial_export 500
--force, -f Allow full regeneration over an existing config (only for all mode) —
--no-cascade Skip FK detection and cascade_from generation —
--no-faker Skip personal data detection —
--no-split Generate a single YAML without splitting by schema —

How tables are sorted:

Symfony Setup

Bundle Registration

The package ships no Flex recipe, so the bundle must be registered manually. Add it to config/bundles.php:

Registering under dev/test matches installation via composer require --dev. If the package is installed for prod (without --dev), register the bundle as ['all' => true].

Bundle Settings

All settings live in a single config/packages/database_dumps.yaml under the database_dumps: root key. The file is optional — defaults apply without it.

⚠️ If the bundle is registered as ['dev' => true, 'test' => true] (the recommended setup above), the section MUST be wrapped in when@dev: / when@test:. Files under config/packages/*.yaml are loaded in every environment, and there is no database_dumps extension in prod — a bare root key breaks the container build: There is no extension able to load the configuration for "database_dumps". The built-in web_profiler.yaml and debug.yaml work the same way. With ['all' => true] no wrapper is needed.

Full key list (shown without the wrapper, i.e. for ['all' => true]):

Row counts come from planner statistics (pg_class.reltuples, information_schema.tables.table_rows, all_tables.num_rows); an exact COUNT(*) runs only when the estimate fits in max_scan_rows or with prepare-analysis --exact-counts. On PostgreSQL column profiles are read from pg_stats and the table itself is not touched; row samples use TABLESAMPLE, never ORDER BY RANDOM(). Tables without statistics are reported as P-1, columns without SELECT privilege as P-2. The only data values that reach the inventory are codes — short ASCII identifiers of low-cardinality columns after a PII gate.

The token does not go here. It lives in .env.local (DBDUMP_LLM_TOKEN), so the file is safe to commit. DBDUMP_* environment variables override values from this file. Per-environment overrides work too — config/packages/dev/database_dumps.yaml.

Config moved in 1.1.24. data_dir, llm and opencode used to live in a separate PHP file, config/database-dumps.php, which the bundle read bypassing DI. It is now an ordinary bundle config. When upgrading, move the values from the old file into config/packages/database_dumps.yaml under the database_dumps: key and delete the old one — the Symfony bridge no longer reads it. Laravel is unchanged: still the published config/database-dumps.php.

Directory Structure (Symfony)

Symfony Commands

Verifying exported dumps (verify-dump) and the import report

verify-dump inspects what actually landed in {data_dir}/dumps/ — neither validate nor check-criteria looks there. It never connects to the database: every dump file is read once for all checks, and only counters and column names leave the file — no data values appear in the report.

Options: -s|--schema, -c|--connection, --inventory (schema inventory, default {data_dir}/analysis/schema_inventory.json; without it inventory-based checks are skipped and the report says so), --format=text|json, --out=PATH. Exit code is 1 on errors.

code level finding
V-1 error child rows reference a parent that is not in the export — the cascade did not restrict the selection; for an edge coming from a DB foreign key the import would reject such a dump
V-2 warning table is configured, dump file is missing
V-3 warning the parent of a relation was not exported (or a FK points to a table outside the config) — nothing to compare with
V-4 error relation column is missing from the dump
V-5 warning value coverage: fewer codes/categories in the dump than in the inventory; the suggestion names the missing codes (codes from pg_stats are only the frequent values, hence not an error)
V-7 error / warning a column without faker whose values look like e-mails, phones or full names (error); a PII-named column with too few values to judge by content (warning)
V-8 error / warning more rows than limit or the sum of sample.criteria quotas (error); full_export disagrees with the inventory (10 % tolerance when the size there is an estimate) or the dump is empty while the table is not (warning)

Edges for V-1 are the union of cascade_from and the inventory foreign_keys: in a constraint-less database the second list is empty today, but once FKs appear the relation is checked without touching the config.

import returns a report with the same rules: errors in it produce exit code 1 even when the transaction succeeded; --out=PATH writes the report as JSON.

code level finding
I-1 error table skipped: dump columns differ from the DB schema (--ignore-schema-mismatch downgrades it to a warning and loads the table)
I-2 error after loading, the table holds a different number of rows than the dump file
I-3 warning a sequence lags behind the column maximum (PostgreSQL) — the application's first INSERT will hit a duplicate key
I-4 error foreign key violated — rows without a parent; deferred constraints are forced with SET CONSTRAINTS ALL IMMEDIATE inside the transaction

Laravel Setup

Provider Registration

The service provider is discovered automatically. If not, register it in config/app.php:

Publishing Configuration

To customize paths, publish the PHP config:

This creates config/database-dumps.php:

Laravel Commands

Before/After Scripts

You can run custom SQL scripts before and after import.

Directory When it runs
docker/database/before_exec/ before importing dumps
docker/database/after_exec/ after importing dumps

Scripts run in alphabetical order. Use numeric prefixes to control the order:

To skip scripts, use --skip-before and --skip-after:

IDE Support (JSON Schema)

The package includes a JSON Schema for dump_config.yaml at resources/dump_config.schema.json. It provides autocompletion and validation in PHPStorm and other IDEs.

Option 1: YAML comment (recommended)

Add to the top of your dump_config.yaml:

The path is relative to the file: for Symfony — relative to config/, for Laravel — relative to docker/database/.

Option 2: PHPStorm manual setup

  1. Open Settings > Languages & Frameworks > Schemas and DTDs > JSON Schema Mappings
  2. Add a mapping:
    • Schema file: vendor/timbrs/database-dumps/resources/dump_config.schema.json
    • File path pattern: dump_config.yaml

Architecture

How Export Works

  1. TableConfigResolver — reads YAML and builds a list of tables to export
  2. DatabaseDumper — manages the export process
  3. TableDependencyResolver — topological sorting of tables by FK (parents are exported first). Circular dependencies are automatically broken via nullable edges
  4. DataFetcher — fetches data from the DB via ConnectionRegistry
  5. CascadeWhereResolver — generates WHERE subqueries from cascade_from for data consistency
  6. RussianFaker — replaces personal data (names, email, phone, gender) with generated values
  7. SqlGenerator — generates SQL: TRUNCATE + INSERT (with NULL for broken FKs) + counter reset + UPDATE (FK restoration)
  8. Result is saved to docker/database/dumps/{schema}/{table}.sql

How Import Works

  1. ProductionGuard — checks we're not on production
  2. TransactionManager — wraps everything in a transaction
  3. TableDependencyResolver — topological sorting of files by FK (parents are imported first), with automatic cycle breaking
  4. SchemaValidator — compares dump columns against DB columns, warns about mismatches
  5. ScriptExecutor — runs scripts from before_exec/
  6. SqlParser / StatementSplitter — splits .sql files into individual statements
  7. Statements are executed against the DB
  8. ScriptExecutor — runs scripts from after_exec/

Platform Differences

The package generates the right SQL depending on the database:

PostgreSQL MySQL Oracle (12c+)
Table names "table" (double quotes) `table` (backticks) | "TABLE" (double quotes, UPPERCASE)
TRUNCATE TRUNCATE ... CASCADE SET FOREIGN_KEY_CHECKS=0 DELETE FROM (FK-safe)
Counters setval() / pg_get_serial_sequence() ALTER TABLE ... AUTO_INCREMENT Stub comment (use after_exec/)
LIMIT LIMIT N LIMIT N FETCH FIRST N ROWS ONLY
INSERT Batch 1000 rows Batch 1000 rows One row per INSERT (no multi-row INSERT)
Random function RANDOM() RAND() DBMS_RANDOM.VALUE

The platform is detected automatically from the DB connection.

Oracle: DELETE FROM is used instead of TRUNCATE TABLE because Oracle TRUNCATE doesn't support CASCADE and is blocked by FK constraints. Sequence reset requires PL/SQL — use scripts in docker/database/after_exec/.

Source Directory Structure

Security

The package prevents accidental imports on production. Import is blocked when the APP_ENV environment variable is prod or predprod.

Testing

Local Development

To use the package from a local folder (without Packagist), add to your project's composer.json:

Then run composer update timbrs/database-dumps — Composer will create a symlink to the local package.

Requirements

Required:

Optional (depends on framework):

Dependency What it's for
doctrine/dbal ^2.13 | ^3.0 | ^4.0 Doctrine DBAL adapter (Symfony)
symfony/console ^4.4 | ^5.4 | ^6.0 | ^7.0 Symfony console commands
symfony/http-kernel ^5.4 | ^6.0 | ^7.0 Symfony bundle registration
illuminate/support ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 Laravel service provider
illuminate/console ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 Laravel artisan commands
illuminate/database ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 Laravel DB adapter

License

MIT License. See LICENSE for details.


Developed by Timur Bayan (Timbrs).


All versions of database-dumps with dependencies

PHP Build Version
Package Version
Requires php Version ^7.1|^8.0
ext-json Version *
symfony/finder Version ^4.4|^5.4|^6.0|^7.0
symfony/yaml Version ^4.4|^5.4|^6.0|^7.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package timbrs/database-dumps contains the following files

Loading the files please wait ...