Best way to perform data migrations

Hi!

What’s the accepted way to perform data migrations with Meteor?

I’ve played with percolate migrations and see the advantages of being able to roll things back, etc…

My current use case is simple though. I’m merely adding a new field to every Doc in a Collection. So, I decided to just import a new module migrations.js in Server Startup.

My plan is to then put all migrations here and then wrap that inside a Meteor.Startup(). However, I’d then have to remove this upon a successful migration and re-deploy (so it doesn’t ever get called again) Not ideal for Prod imo.

This is the part I don’t like and an advantage that I see percolate migrations can give me. My concern with the latter is that it seems too general in terms of version of a migration. I feel like I can’t isolate migrations with this. I.e. I just want to update 1 collection.

Also, do I still have to write the down() fn to revert the changes? I feel like the package may be too powerful and can introduce other issues.

How does the community here retroactively update Documents? Thanks!

2 Likes

I have used percolate:migrations for a long time. I have never written down() migrations and I never had a need for it. You can make your migrations as atomic as you like - I only ever migrate one collection at a time, so a deployment could contain multiple migrations, which are executed one after the other the first time the code is run in a given database environment. It’s a lightweight package and it does the job well.

For very simple migrations, I just put them in a Meteor method and manually call the method after deploy. No need then to make sure they’re repeatable or only called once. (Methods are role-restricted of course).

Do you then remove the call to the method (and the method itself) and re-deploy?

I manually call the migration method, so no need to remove or re-deploy.

You call it manually by making an external call to the method from curl or something? If so, how do you expose the method, are you using a lib. I’ve used JsonRoutes before

Using a Meteor Method in the server-side code. You call it from the browser console, Meteor.call(‘method_name’).

1 Like

I am using the percolate:migrations package for years now and never faced problems with it. You don’t have to implement down(), and I actually never did.

percolate:migrations will also remember which up()s have already been called by storing the last database version number in the database. Thus, they won’t be called again. Only if your database is completely blank, all the up()s run, but in this case there’s nothing to do, and the database version counter immediately jumps to the latest up(). This would only cause problems if your up()s also perform side-effects, like requesting data from external services.

If an up() fails, percolate:migrations will stop, set a locked flag in the database and put a warning on the console. Once you resolved the issue, you can manually reset the locked flag to try again. In practice, this only happens if you roll-back your app to a previous state and thus the database version is out of sync with your app.

1 Like

Here is the method i have been using since i use Meteor : i have a Migrations collection, and some code that is loaded at startup :

Meteor.startup(function() {
  if (!Migrations.findOne({ name: "doStuff with foobar"})) {
    //do migration
    console.log("doSuff with foobar completed");
    Migrations.insert({ name: "doStuff with foobar" });
   }
}

So i can test my migration on my local computer, and when the code is deployed on the server it’s executed one time and only one time.
Simple and limited, but has been working without problem so far.

1 Like

Mm…even though the code is called only once, do you end up removing it from your production code?

No, what concerns do you have ?

Just having unused code in production. Maintainability, etc. Not a big concern, but jw what others think