nowo-tech / migrations-kit-bundle
Symfony bundle providing migration helpers: schema checks (table/column/index exists) and array-based migration definitions. Use in Doctrine Migrations with Symfony 7|8.
Package info
github.com/nowo-tech/MigrationsKitBundle
Type:symfony-bundle
pkg:composer/nowo-tech/migrations-kit-bundle
Requires
- php: >=8.2 <8.6
- doctrine/dbal: ^2.13 || ^3.0 || ^4.0
- doctrine/doctrine-bundle: ^2.8 || ^3.0
- doctrine/migrations: ^3.5 || ^4.0
- symfony/config: ^7.0 || ^8.0
- symfony/dependency-injection: ^7.0 || ^8.0
- symfony/http-kernel: ^7.0 || ^8.0
- symfony/yaml: ^7.0 || ^8.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpunit/phpunit: ^10.0
README
Symfony bundle that provides helpers for Doctrine Migrations: schema checks (table/column/index exist) and array-based migration definitions, so you can write idempotent migrations without repeating SQL and with safe checks. For Symfony 7 and 8 · PHP 8.2+ · Doctrine DBAL 2.x–4.x and doctrine/migrations 3.x–4.x.
⭐ Found this useful? Install from Packagist · Give it a star on GitHub so more developers can find it.
Table of contents
- Quick search terms
- Features
- Installation
- Configuration
- Usage
- Documentation
- Requirements
- Demo
- Development
- License & author
Quick search terms
Looking for Doctrine migrations helpers, table exists migration, column exists check, idempotent migrations, migration schema check, Symfony Doctrine Migrations, declarative schema migrations? You're in the right place.
Features
- ✅ SchemaChecker —
tableExists,columnExists,indexExists,hasPrimaryKey,foreignKeyExists,listTableColumns; no container injection:new SchemaChecker($this->connection) - ✅ CreateTablesService — apply declarative definition arrays (MDK format); create/drop tables, add/drop/rename/modify columns, add/drop indexes, foreign keys; call
apply($schema, $definition)with introspected schema and add each returned SQL with$this->addSql() - ✅ MigrationDefinitionKeys (MDK) — constants for definition keys (
tables,columns,primary_key,indexes,foreign_keys,drop_columns, etc.); use alias MDK in code; see DECLARATIVE_SCHEMA.md - ✅ Array of associative arrays — columns, indexes, FKs defined as arrays of items (each with
name/columns,type,drop,rename, etc.); no raw SQL for schema changes - ✅ Recommended practice — use separate migrations: first add column, then add index, then add foreign key; when dropping, first drop indexes then drop columns (see docs/USAGE.md). The bundle always applies operations in the correct order (drops: FK → index → column; adds: columns → PK → indexes → FKs), but phased migrations are more stable
- ✅ Compatible with Doctrine DBAL 2.x, 3.x, 4.x and doctrine/migrations 3.x, 4.x
- ✅ SQLite, MySQL and PostgreSQL — schema checks and migrations work with all three
- ✅ Symfony Flex recipe (register bundle + config; see docs/INSTALLATION.md)
- ✅ Demos for Symfony 7 and 8 with example migrations (create table, add/rename/drop columns, indexes, FKs); Make targets to view migration SQL (
migrate-verbose,migrate-dry-run,migrate-write-sql)
Installation
composer require nowo-tech/migrations-kit-bundle
With Symfony Flex, the recipe (when enabled) registers the bundle and creates the config file automatically. Without Flex, see docs/INSTALLATION.md for manual steps.
Manual registration in config/bundles.php:
<?php return [ // ... Nowo\MigrationsKitBundle\NowoMigrationsKitBundle::class => ['all' => true], ];
Configuration
Create config/packages/nowo_migrations_kit.yaml (optional; defaults to connection: default):
nowo_migrations_kit: connection: default # Doctrine connection for the injected SchemaChecker service
Full options: docs/CONFIGURATION.md.
Usage
In your migration, use the migration's connection — no service injection required:
SchemaChecker — run SQL only when something does not exist:
use Nowo\MigrationsKitBundle\Migration\SchemaChecker; $checker = new SchemaChecker($this->connection); if (!$checker->tableExists('app_settings')) { $this->addSql('CREATE TABLE app_settings (...)'); } if (!$checker->columnExists('app_settings', 'created_at')) { $this->addSql('ALTER TABLE app_settings ADD created_at DATETIME NOT NULL'); }
CreateTablesService — apply a declarative definition (MDK format); the service returns the list of SQL statements; add each with $this->addSql():
use Nowo\MigrationsKitBundle\Migration\CreateTablesService; use Nowo\MigrationsKitBundle\Migration\MigrationDefinitionKeys as MDK; use Nowo\MigrationsKitBundle\Schema\Definition\SchemaDefinitionParser; $schema = $this->connection->createSchemaManager()->introspectSchema(); $service = new CreateTablesService($this->connection, new SchemaDefinitionParser()); $definition = [ MDK::TABLES => [ 'users' => [ MDK::COLUMNS => [ ... ], MDK::PRIMARY_KEY => [ ... ] ] ] ]; foreach ($service->apply($schema, $definition) as $sql) { $this->addSql($sql); }
More examples: docs/USAGE.md and docs/EXAMPLE.md.
Documentation
| Document | Description |
|---|---|
| Installation | Requirements, Flex and manual install |
| Configuration | All options and defaults |
| Usage | SchemaChecker, CreateTablesService, MDK, rename column that has index, viewing SQL before running |
| Example | Full migration examples |
| Declarative schema | Definition format (MDK) and apply() |
| Demo migrations reference | Use cases matrix, expected SQL per migration, safety, make write-sql-reference-mysql |
| Demo | Run demos (Symfony 7/8), Make targets, field dictionary (AuditFields), MySQL 8 (symfony8/docs/MIGRATIONS_MYSQL.md) |
| Flow diagrams | Mermaid flowcharts: apply() flow, checks, DBAL API per scenario |
| Changelog | Version history |
| Upgrading | Upgrade notes between versions |
| Roadmap | Vision and future ideas |
| Security | Reporting vulnerabilities |
| Contributing | How to contribute and code style |
| Release | Release checklist (for maintainers) |
Requirements
- PHP >= 8.2
- Symfony 7 or 8 (^7.0 || ^8.0)
- doctrine/doctrine-bundle ^2.8 || ^3.0
- doctrine/dbal ^2.13 || ^3.0 || ^4.0
- doctrine/migrations ^3.5 || ^4.0
Databases: the bundle is compatible with SQLite, MySQL and PostgreSQL. Use the same migrations and helpers; platform-specific SQL is handled by Doctrine DBAL.
See docs/INSTALLATION.md and docs/UPGRADING.md for compatibility notes.
Demo
Demos for Symfony 7 and 8 are in demo/symfony7, demo/symfony8. Each includes example migrations using CreateTablesService and the MDK format (create table, add/rename/modify/drop columns, indexes, foreign keys), plus a field dictionary (migrations/FieldDictionary/AuditFields) for reusable audit columns (timestamps, created_by/updated_by with FK in two phases). From the bundle root: make demo-up-symfony8 then make demo-migrate-symfony8. Always check SQL before applying: use make migrate-dry-run (or doctrine:migrations:migrate --dry-run -vvv). See docs/USAGE.md for all options (migrate-dry-run, migrate-write-sql, migrate-verbose). demo/README.md and each demo/symfony*/README.md have run instructions.
Development
Run tests and QA with Docker: docker compose up -d --build && docker compose exec php composer install && docker compose exec php composer test (or composer test-coverage, composer qa). Without Docker: composer install && composer test. See Makefile for all targets.
License
The MIT License (MIT). Please see LICENSE for more information.
Author
Created by Héctor Franco Aceituno at Nowo.tech