Schema Migration Clarity

Hi,

I’ve just done my first database schema migration using the percolatestudio:meteor-migrations package.

I managed to get it to work and fix a problem I had on my server, but I wanted a bit explanation on how to use and what needs to be done depending on what has changed in the schema.

The first migration that I just made did not require any data changing code within the ‘up’ function. This was the migration code:

Migrations.add({
  version: 1,
  up: function() {
    console.log('Migrate to version 1');
  }
});

The only change that was made was to a field’s autoValue property.

I’d like a bit more information on what situations would require some code in the ‘up’ function. I have struggled to find much information on it.

Does the ‘up’ function only require some more implementation when the schema affects the actual structure of a document? Not just it’s autoValue’s / defaultValue’s?

What other schema changes would not require any update code?

Hey,

Migrations are most commonly used when changing your application code requires some one-time action on the next startup. For example you have a MongoDB collection that uses a User schema which stores data about your users favorite food like:

{
  _id: '1',
  favorites: ['bananas'],
}

But you add a new feature to your application that expands this functionality and also allows users to store different favorite things so instead of a string, you would like to store an object with a type value like so:

{
  _id: '1',
  favorites: [{ type: 'food', value: 'bananas' }, { type: 'programmingLanguage', value: 'JavaScript' }],
}

Now, if you just changed the schema and your application code, but didn’t adjust your existing database data that still stores the values as strings it would create inconsistencies and bugs in your application.

This is what the up function in the Migration is for - there you will write a MongoDB query that will modify your existing documents and turn your string values into appropriate objects. Conversely, you would write the reverse action in the down function - here you want to turn all your objects into strings instead.

Also keep in mind that migrations can do anything - it doesn’t have to be related to your database.

It seems that in the example you provided you are trying to use migrations as a versioning system for your application - this is better done by other tools, for example using git tags.

2 Likes

Basically this is where you state what changed in the migration, it’s used to consistently reflect the changes in the existing data (to avoid bugs).

For example if you removed a field from a collection schema you should do :

up: function() {
 Collection.update(
   { ... },
   { $set: { oldProperityToRemove: undefined }}, 
   { multi: true })
}

If you’ve change the default value of a field you should do something like :

up: function() {
 Collection.update(
   { modifyedProperity: { $in: [ undefined, null ]},
   { $set: { modifyedProperity: "defaultValue" }}, 
   { multi: true })
}

It can also be used for non database related work. For example :

  • implement an external service such as a search engine needing data from your db
  • modifying resources (moving files, creating alternate versions of images, etc.)
1 Like

@nschwarz @wadamek

Thank you! That makes things a bit clearer. I guess I’ll learn it better as and when I need to use it.