1. Nashville symfony Group
The Art of Doctrine Migrations
Feb 2nd, 2010
Ryan Weaver
@weaverryan
iostudio.com
www.thatsquality.com
2. Nashville symfony Group Feb 2010
So you've updated your code, now to update
your database...
PhpMyAdmin: post-it notes, pizza & beer
SQL deltas:
Pros: familiar syntax, tools available
Cons: not systematic, db-specific, disconnected from ORM
Doctrine Migrations:
Pros: systematic, generate automatically, written in Nashville
(probably)
Cons: were a pain in the ass (until now), still a bit quirky
3. Nashville symfony Group Feb 2010
A PHP file with simple
directions on how to
update your database
Each file is prefixed by a
number, which determines
its ordering:
/lib/migration/doctrine/
1_add_brilliant_idea_table.php
2_add_good_people_table.php
3_add_desc_field_to_idea.php
4. Nashville symfony Group Feb 2010
Tracking Versions
Doctrine keeps track of
your db's “version” via
migration_version table
/lib/migration/doctrine/
1_add_brilliant_idea_table.php version 1
2_add_good_people_table.php version 2
3_add_desc_field_to_idea.php version 3
4_modify_some_column.php version 4
35_alternatively_numbered.php version 5
5. Nashville symfony Group Feb 2010
Take a deep breath and migrate:
./symfony doctrine:migrate [migration #]
6. Nashville symfony Group Feb 2010
Writing Migrations
Create a blank migration file:
doctrine:generate-migration name
Creates a blank file in lib/migration/doctrine
(e.g. 1265085881_add_another_table.php)
Use the rich API to
make changes
www.doctrine-project.org/Doctrine-
Cheat-Sheet-1.1.pdf
8. Nashville symfony Group Feb 2010
Generate Migrations
For an existing database & project with no migrations:
doctrine:generate-migrations-db
• Generates migration classes for everything to date
• For example, for a project with 75 tables, this would generate
76 migration classes
• (1 per table + 1 giant class for all indexes and foreign keys)
This gets you “caught up”, but only works once.
9. Nashville symfony Group Feb 2010
Migration-diff tool
Generates new migration class(es) based on some schema
change
1) Make a change to your schema (e.g. add a column)
2) Run the diff tool task:
doctrine:generate-migrations-diff
3) Rebuild your model
doctrine:build --all
This runs a “diff” between your new schema and your
old model files.
Lame/Warning: If you rebuild your model before running the diff
tool, no changes will be recognized
10. Nashville symfony Group Feb 2010
Filename Conventions
Generated migrations take one of these 2 forms:
263866565_migration_name.php
263866565_version15.php
We recommend renaming to include the version #:
version1_migration_name.php
263866565_version15.php
11. Nashville symfony Group Feb 2010
Model Name Conventions
Generated migrations take one of these 2 forms:
class Version15
class MigrationName
We recommend naming the class by the version #:
class Version 15
12. Nashville symfony Group Feb 2010
Data Migrations – easy, but...
Also can use:
- preUp()
- preDown()
This will break
eventually, when
you make
changes to the
BrilliantIdea model
(e.g. in 2 months,
you remove the
name field)
13. Nashville symfony Group Feb 2010
Doctrine Migration – Ruining your day
1) NEVER mix foreign-key changes with table or
column changes Major
$this->createTable('brilliant_idea',...) migration
$this->createForeignKey('brilliant_idea', …) foul
2) If you care, be careful with your index names
Name 'product_slug' becomes 'product_slug_idx'
14. Nashville symfony Group Feb 2010
Tools – MySQLdiff (http://www.mysqldiff.org/)
• Simple: compares two databases and gives you a list of their
differences
– build-all-reload your main database
– Migrate your test database
15. Nashville symfony Group Feb 2010
Discussion Notes from the Presentation
Migration Failures
Suppose you're migrating from version 2-10 and migration
#5 fails:
●
Migrations 6-10 will continue to try to run
●
The migration_version table will still be set to 2 after
the migration, even though versions 3 & 4 were
successful
16. Nashville symfony Group Feb 2010
Discussion Notes from the Presentation
generate-migrations-db
●
In theory, this task compares your db to your models
and generate migrations based on the difference.
●
After weeks of dev, all migrations could be generated
at once
●
At least 2 bugs exist in this task:
●
http://pastebin.com/f7e11c784
●
Models prefixed with a lowercase letter will not
work. But, this does not affect most MACs
17. Nashville symfony Group Feb 2010
Discussion Notes from the Presentation
Resetting your migrations
●
To battle “broken” migrations that result from data
migrations that reference no-longer-used fields, it
may be a good idea to adopt a strategy of periodically
“resetting” your migrations:
●
Delete all migration files
●
Run doctrine:generate-migrations-db
●
Manually set your migration_version number to the
last, newly-generated migration file
18. Nashville symfony Group Feb 2010
Discussion Notes from the Presentation
Autoloading Bugs in generate-migrations-diff
●
When using the diff tool, you may get an error such
as: “Cannot find class PrfxSomeClass”
●
The diff tool generates temporary models and in
some cases (specifically doctrine model subclassing)
will require the files in the wrong order
●
There is a hack (try the autoload.yml hack):
●
http://trac.symfony-
project.org/ticket/7272#comment:13
19. Nashville symfony Group Feb 2010
Questions? Idea Bubbles?
Ryan Weaver
@weaverryan
iostudio.com
www.thatsquality.com