Before the Scary Migration
Every developer has run a migration they were not sure about and felt the small cold moment afterwards. This chapter removes it, in two commands, and explains why this particular feature could only come from the thing that installed your database.
The problem
A destructive migration cannot be undone by
migrate:rollback. The down()
method restores the schema; it cannot restore the
column you dropped, because the data went with it. And in
local development the data is often worth more than it
sounds: three weeks of hand-made test cases covering the
edge conditions you had to reason about, which a fresh
seed does not contain.
So people do one of two things. They avoid the experiment — writing the migration defensively, never trying the cleaner schema — or they run it and lose an afternoon rebuilding fixtures. Both are the same tax, paid differently.
The hard way
You can do this yourself:
mysqldump to a file, remember where you put
it, remember the flags, restore with the inverse command,
remember which of the four dumps in your Downloads folder
was the right one. It works, and the number of people who
actually do it before every risky migration is
approximately zero, because the ceremony is longer than the
migration.
Two commands
grove db snapshot --db myapp --note "before migrate"
# ...run the scary migration...
grove db list
grove db restore <id>
Data restored exactly as it was. The note is not
decoration — a week later, grove db list
with five snapshots in it is unreadable without one.
Snapshots live under Grove's own directory rather than in your project, which keeps a database dump out of your repository and out of your build context. MySQL and PostgreSQL snapshots are plain SQL dumps — readable, greppable, restorable by hand if you ever want to. An ElyraSQL snapshot is a hot, consistent copy of its single database file, taken while it serves.
Why only a supervisor can do this
This is the chapter that makes the argument for the whole course, so it is worth stating directly.
A tool that merely connects to your database can
dump it. Only a tool that owns it knows which
engine is running, on which port, with which credentials,
for which project — without being told, every time,
by you. Grove installed the database, so
grove db snapshot needs no connection string:
it already knows.
That is the same property that made grove env
correct in chapter 6 and per-site PHP routing possible in
chapter 5. Each is small on its own. Together they are the
difference between a collection of tools and an
environment.
Make it a habit
Snapshot before a migration you have not run before.
Snapshot before running someone else's migration on
your data. Snapshot before migrate:fresh --seed
on a database you have been building up by hand.
It costs seconds and it changes what you are willing to try — which is the real benefit. The best version of a schema is usually the third one you attempt, and you only get to the third if the first two were cheap.
What you learned
- down() restores the schema, not the data. Hand-made local fixtures are worth more than they sound.
- Two commands, with a note, because five unlabelled snapshots are as good as none.
- Snapshots live in Grove's directory, not in your repository or your build context.
- Owning the database is what makes it one command — the same property behind grove env and per-site PHP.
- Cheap experiments change what you attempt. The best schema is usually the third one.