Keeping a bunch of database schemas synchronized can be a real challenge. If you try doing it by hand, life is going to be difficult. Fortunately for PHP developers, Doctrine Migrations provides an easily scriptable solution, even if your project doesn't use the Doctrine ORM.
6. How it works
Generate a new migration file
Write SQL scripts
Version20170512192814.php
Execute the migration
Doctrine records the update
20170512192814
12. Lessons
Learned
Challenges in multi-developer situations
Try to avoid using execute --up and execute --down
DM tries to use symfony EM defined in config.yml for connection
Use --db-configuration=/path/to/file to specify
separate credentials
Even better, create a wrapper script and use Env.php to detect
environment and load correct credentials
16. References
Doctrine Migrations Documentation
• http://www.doctrine-project.org/projects/migrations.html
Article on using stand-alone Doctrine Migrations
• https://akrabat.com/using-doctrine-migrations-outside-of-doctrine-
orm-or-symfony/
Notes for inclusion in SMART IRB Exchange
• https://github.com/vanderbilt/irbshare/wiki/Using-Doctrine-
Migrations
Editor's Notes
Present tool for synchronizing dbase
Bryce – General overview / simple use case
Patrick – Lessons learned in more complex scenario
Goal – Drink the DM KoolAid
My situation – 8 databases to keep in sync.
IRBChoice and SIE are same core app running with different features in different environments.
Tried making changes in SQL Developer while coding, then remembering 1) what changes I made and 2) to make those changes to other dbases
Result: Inevitably something would crash because I forgot a change.
Never sure if dbases in sync
Now, I write SQL in a script file to modify dbase.
I manually run script on Docker to upgrade dbase.
When I push code to servers, deploy script runs migration code.
I don’t have to remember my dbase changes, or worry that code is out of sync with dbase.
With a name like “Doctrine Migrations” you may think you have to use Doctrine ORM.
I’m using it on Zend Framework with Oracle DB.
Patrick is using with Symfony & Doctrine also on Oracle.
Can add to any project via Composer dependency
Once DM is installed, these are steps for making changes to your dbase
No more on-the-fly db changes in GUI.
Keeping 8 dbases in sync requires discipline, and first step is scripting ALL changes.
DM is configured with a directory where all migrations are stored.
First step in migration is creating a new file.
File is specially named with timestamp. Have to use this naming scheme.
If desired, you can organize scripts in subfolders and DM will still find them all.
ALL dbase modifications in script / SQL. No more GUI tweaks.
“Generate” gave us this framework. All we do is fill out the ‘up’ and ‘down’ methods.
Example: Add two columns to table.
Each command is separate entry, but you can use PL/SQL code.
Write “down” function to back out. This is important. If the “Up” crashes, it doesn’t crash gracefully.
I test these – running ‘up’ and then ‘down’ and then ‘up’ in Docker until it works without failures.
Can execute manually or make it part of deployment script.
- Migrate before or after code changes? After. If code change fails, don’t have to run migration
To roll back, select version to execute “down”.
When a migration completes successfully, DM records the version ID in single-field table.
On next migration, the versions listed in directory are compared with those in the table. If any missing, they are executed in order.
Story: Running ‘migrate’ on loaded db that did not have initial setup migration marked. Tried to build from beginning.
That’s the basics. Any questions on the fundamentals before Patrick talks about some of the challenges?
If lots of ppl are running execute --down/--up in random orders, it can cause headaches
The db connection used by symfony shouldn’t have access to alter schemas, so DM needs a separate connection
This wrapper script detects the environment and loads the correct configuration file, so the user doesn’t have to worry about it (and can’t make a mistake!!!)
Updating a table to use a sequence for the primary key column. Since the table has existing data, we need to query it and get the current number of rows so we know where to start the sequence.