migrate
migrate copied to clipboard
Writing migrations for v3
I'm upgrading from v1 just now, and I'm trying to understand why migrations aren't wrapped in transactions anymore. I've seen the issues about some queries not working, so I can see the need for non-transactional migrations, but not to the point of making all migrations raw by default.
I assume the idea is that all migrations must be single-statement (judging by the Postgres examples), so they become "transactions" by themselves, but isn't this unsafer than v1, since you can write a multi-statement (intentionally or by accident) and forget to wrap it in BEGIN/COMMIT
? Resulting in a messier cleanup if it goes wrong?
Also, making a separate up/down
seems to be way too verbose. I've checked my project, and I have 752 semicolons (read statements, roughly) in its migrations. And it isn't even that large. So many files would make it much more challenging to analyze the evolution of a schema.
More so, having to do "1 statement = 1 file" would make simple things, like defining mutually referencing tables and whatnot, a bit harder. Could be mistaken though.
And then there's the extra step of having to "force" a migration if something goes wrong, instead of just correcting the failed migration and re-running it.
Do you have a real world example of a project using v3 with Postgres? Are you/they happier with v3?
Thanks for your feedback!
One migration file can have multiple statements. It's up to the user to wrap several statements into transactions. Before that the driver was doing that which lead into conflicts. The current approach is cleaner. (No surprises)
Separate up/down migration files are handy, because existing database utilities continue to work. (again no surprises with custom markup introduced by migrate).
Force
is a great protection to keep schemas in sync. If a migration fails in production, human input is always needed. I agree that in development the workflow could be smoother.
I can only speak for myself, but we are using migrate with postgres at @templarbit.
It would be possible to create a new source driver that introduces custom markup to combine the up and down migration into one file.
Thanks for a quick reply!
I understand that a single file can have multiple statements. My concern is that a user may forget to wrap it in BEGIN
and COMMIT
(being used to v1 or tools from other ecosystems, like Knex), and he will never notice the mistake, until the migration fails, likely leaving a mess behind.
About separate up/down
files - sorry, I've phrased it wrong, I was talking about the "one SQL statement per file" approach advertised in the Postgres examples, and the way it's less human-readable than the regular approach of "one new feature = one new migration file". In my case that would be 752 files, which is a usability downgrade.
About forcing, I understand why it's there too, but with "everything runs in a transaction" in v1 there was no need in it at all. The less I need to remember / think about while doing something as dangerous as touching production data, the better.
Semi-offtopic: In general, I choose to never write down-migrations, because undoing a migration is never a simple task. If you want to go back on a production database, then it will be either super simple or it will require a custom migration (or even a standalone script), as to avoid data loss and whatnot. Can't see a pre-coded down file fitting all possible situations.
And the reason why I asked about a real world example was that I just wanted to know what kind of conventions or team policies people have with migrate v3. I'm not actively working on my project right now, so this is no big deal, but still, would be nice to know, for future reference. Basically, I'm just wondering what's behind the @TODO
in MIGRATIONS.md
🙂
I was also wondering about this: I think I slightly preferred the old style of the drivers doing it for us, but I can understand the reasoning.
At the very least, it'd be great if migrate create
stuck the BEGIN; ... COMMIT;
in to help us remember.