Skip to content

Instantly share code, notes, and snippets.

@notchris
Created March 20, 2023 18:05
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notchris/c5155073bbbb08a487b349c52f6823ae to your computer and use it in GitHub Desktop.
Save notchris/c5155073bbbb08a487b349c52f6823ae to your computer and use it in GitHub Desktop.

Creating Migrations with PayloadCMS

First, check out an official repo by the Payload team that shows a couple of migrations examples. https://github.com/payloadcms/migrate-mongo-example

Setting up your environment for migrations

Payload uses the package migrate-mongo to define migration config files. I installed it globally but feel free to install it however you'd prefer.

Once installed, cd to your Payload root /payload and run migrate-mongo init which will create a migrations folder as well as a migrate-mongo-config.js file.

Start by opening the migrate-mongo-config.js and configuring the url property. This should be the same URL you specified in your .env. You can also remove the databaseName property because it's already in your url.

When complete, your config will look like the following (with comments, etc).

const  config = {
mongodb: {
	url:  "mongodb://10.2.1.224/example",
		options: {
			useNewUrlParser:  true, // removes a deprecation warning when connecting
			useUnifiedTopology:  true, // removes a deprecating warning when connecting
		}
	},
migrationsDir:  "migrations",
changelogCollectionName:  "changelog",
migrationFileExtension:  ".js",
useFileHash:  false,
moduleSystem:  'commonjs',
};

module.exports = config;

Creating a simple migration

While there are very complex scenarios that I don't know how to write migrations for, most people will likely want to add / remove / update basic fields. Here is an example I had. I was asked to remove a text field from my Users collection. The field itself was titled dealership and was originally used to list the Dealership a user worked for (Car sales). We could easily remove the field in our Users collection config, but that will leave all the data in our Mongo DB which isn't very tidy. Here is how to remove a single text field from a collection using a migration (Note: you still need to remove the field from your Collection config too).

First we want to create the migration file. Every new migration will generate a migration-script template in the migrations folder. When creating a migration, please use a name that is very clear of what the migration is doing, for your own sake.

Create the new migration:

migrate-mongo create remove-dealership-field-from-user-collection

Which creates 20230320173021-remove-dealership-field-from-user-collection.js in your migrations folder.

Open the created file in your editor and you'll notice that it exports two functions up and down. up is responsible for applying the new migration to your database while down is for reverting a migration.

Since I just wanted to remove a single field, my migration was quite simple. (Note: I'm writing this tutorial on stackedit.io, so the formatting is all ******.

module.exports = {
async  up(db, client) {
	await  db.collection('users').updateMany({ },
		{ $unset: { dealership:  "" } }
	)
},

async  down(db, client) {
	await  db.collection('users').updateMany({ },
		{ $set: { dealership:  "" } }
	)
}
};

Nothing too crazy going on here, you can see I'm removing the field in the up function and re-setting it in the down function to an empty string.

At this point I felt pretty safe running my migration and knew if it failed I could always roll back.

Running a migration is simple as running migrate-mongo up, which grabs the latest created migration and executes it.

You can check the status of the migration via migrate-mongo status.

After running the command, I opened up Studio 3T (Wish I knew an alternative) and checked to make sure the field was removed, and it was!

Links / other notes

@cookernetes
Copy link

An alternative for MongoDB for Studio 3T is MongoDB’s official ‘Compass’ app if you don’t know already.

@notchris
Copy link
Author

An alternative for MongoDB for Studio 3T is MongoDB’s official ‘Compass’ app if you don’t know already.

I've heard of Compass I'll check it out though as I've never used it. Wishing I had something as simple as SQLITE DB Viewer :*(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment