Multi-namespace migrations with Doctrine
Multi-installation applications (such as example Wordpress, Magento, Drupal or similar) have in common a mechanism to define optional Modules/Plugins/Extensions.
Modules can defines migrations, but when modules have dependencies to other modules, then the execution order depends on those dependencies and not only on the chronological order.
This package solves this issue by providing a pre-configured Symfony 5 application with doctrine/migrations 3.0 enabled. The application is able to automatically discover and run migrations provided by bundles.
The example application has the following structure:
+---------------+
| |
+----- | App |-----+
| | | |
| +---------------+ |
| |
| |
| |
| |
| |
+---------------+ +---------------+
| | | |
| Customer | | Order |
| | | |
+---------------+ +---------------+
|
|
|
|
+-------+-------+
| |
| Invoices |
| |
+---------------+
- there is the main application
App
- there is a
Order
module (bundle) that depends onApp
- there is a
Customer
module (bundle) that depends onApp
- there is a
Invoice
module (bundle) that depends onCustomer
Dependencies are inferred from the composer.json
file that each bundle has.
All the modules provide some doctrine migrations but each module owns only its migrations. When migrations are executed the dependencies are resolved and migrations are executed accordingly.
Each bundle auto-registers the migrations to run, without the need to hardcode any directory location or dependency.
This solution for simplicity uses sqlite
as database,
but obviously can be applied to any other RDBMS supported by doctrine.
Preview
Here some previews of the content for this solution.
File structure:
.
├── bin
│ └── console
├── public
│ └── index.php
├── config
│ ├── bootstrap.php
│ ├── bundles.php
│ ├── packages
│ │ ├── cache.yaml
│ │ ├── doctrine_migrations.yaml
│ │ ├── doctrine.yaml
│ │ ├── framework.yaml
│ │ ├── prod
│ │ │ ├── doctrine.yaml
│ │ │ └── routing.yaml
│ │ ├── routing.yaml
│ │ └── test
│ │ └── framework.yaml
│ ├── routes
│ │ ├── annotations.yaml
│ │ └── dev
│ │ └── framework.yaml
│ ├── routes.yaml
│ └── services.yaml
├── migrations # App migrations
│ └── Version20200519061824.php
├── src
│ ├── Controller
│ ├── DependencyInjection
│ │ └── **.php
│ ├── DoctrineMigrations
│ │ └── **.php
│ └── Kernel.php
├── var
│ ├── cache/
│ └── log/
├── plugins # Plugins folder (can be any composer package)
│ ├── customer
│ │ ├── composer.json
│ │ ├── migrations
│ │ │ └── Version20200519061904.php
│ │ └── src
│ │ └── GoetasShopCustomerBundle.php
│ ├── customer-invoices
│ │ ├── composer.json
│ │ ├── migrations
│ │ │ └── Version20200519061858.php
│ │ └── src
│ │ └── GoetasShopCustomerInvoicesBundle.php
│ └── order
│ ├── composer.json
│ ├── migrations
│ │ └── Version20200519061909.php
│ └── src
│ └── GoetasShopOrderBundle.php
├── composer.json
├── composer.lock
├── symfony.lock
├── vendor
└── README.md
Migration output:
$ bin/console doctrine:migrations:migrate -n -vv
[notice] Migrating up to GoetasShop\DoctrineMigrationsDemo\Order\DoctrineMigrations\Version20200519061909
[info] ++ migrating App\DoctrineMigrations\Version20200519061824
[debug] SELECT 'Migrate UP App'
[info] Migration App\DoctrineMigrations\Version20200519061824 migrated (took 22.6ms, used 12M memory)
[info] ++ migrating GoetasShop\DoctrineMigrationsDemo\Customer\DoctrineMigrations\Version20200519061904
[debug] SELECT 'Migrate UP Customer'
[info] Migration GoetasShop\DoctrineMigrationsDemo\Customer\DoctrineMigrations\Version20200519061904 migrated (took 0.2ms, used 12M memory)
[info] ++ migrating GoetasShop\DoctrineMigrationsDemo\CustomerInvoices\DoctrineMigrations\Version20200519061858
[debug] SELECT 'Migrate UP CustomerInvoices'
[info] Migration GoetasShop\DoctrineMigrationsDemo\CustomerInvoices\DoctrineMigrations\Version20200519061858 migrated (took 0.3ms, used 12M memory)
[info] ++ migrating GoetasShop\DoctrineMigrationsDemo\Order\DoctrineMigrations\Version20200519061909
[debug] SELECT 'Migrate UP Order'
[info] Migration GoetasShop\DoctrineMigrationsDemo\Order\DoctrineMigrations\Version20200519061909 migrated (took 1.5ms, used 12M memory)
[notice] finished in 66.9ms, used 12M memory, 4 migrations executed, 4 sql queries