# Running a content migration https://www.sanity.io/learn/course/handling-schema-changes-confidently/running-a-content-migration.md Use field validation to validate if the migration was successful. Back up the dataset for safe measure. Run the content migration and verify that it went well. ## Using validation to validate a migration Before diving into the migration, we want to do one more thing: make the **Event format** field **required**. The primary reason is that we always want to have information for this with an event, but it will also let us validate that the content migration has been successful later on. 1. Add the `rule.required()` validation rule to the **Event format** field ```typescript:apps/studio/schemaTypes/eventType.ts defineField({ name: 'format', type: 'string', title: 'Event format', options: { list: ['in-person', 'virtual'], layout: 'radio', }, validation: (rule) => rule.required(), }), ``` If you save this change and run the `sanity documents validate -y` command again, you should get a lot of errors like this on the `event` document type: 1. **Run** the following to validate all documents ```sh # in apps/studio pnpm dlx sanity@latest documents validate -y ``` You should get errors on all event documents like: ```sh:Terminal output ERROR event AUoLUkEDo6CVeRx5svBpXH └─ format ........................ ✖ Required ``` When you finish the content migration, this validation error should disappear. You are now ready to prepare the content migration to move the values over from the old to the new field in all the existing documents. ## Dry-running a content migration You are now ready to do a dry run to check how the migration script will affect your content in the dataset. You won't need to add a flag to dry run this, migrations are dry run by default. 1. **Run** the following to "dry run" the migration ```sh # in apps/studio pnpm dlx sanity@latest migration run replace-event-type-with-event-format ``` If run successfully, this command should output a list of patches for each event document, looking like this: ```text patch event AUoLUkEDo6CVeRx5svBpBB └─ eventType ..................... unset() patch event AUoLUkEDo6CVeRx5svBiyh └─ format ........................ setIfMissing("in-person") ``` ### Backing up the dataset It’s a good habit to export the dataset before running a content migration, especially if you do it on production content. This way, you have a backup that you can import if something goes wrong or you make an error (it happens to us all). 1. **Run** the following to export your production dataset with the Sanity CLI ```sh # in apps/studio pnpm dlx sanity@latest dataset export production ``` This will export all your documents into a newline-delineated JSON file (`.ndjson`) and assets in their folder as a `production.tar.gz` file. If you want to “reset” your dataset to its state before the content migration, you can run the following command: ```sh # in apps/studio pnpm dlx sanity@latest dataset import production.tar.gz production --replace ``` Note that the `--replace` will _overwrite_ documents with the same `_id`. With this backup, you can execute the content migration knowing that you have a way to restore the dataset if something goes wrong. ## Executing a content migration With the dataset backup in place and having verified that the content migration script outputs the changes we want, you are now ready to move a lot of data in one swoop. 1. **Run** the content migration with the `--no-dry-run` flag ```sh # in apps/studio pnpm dlx sanity@latest migration run replace-event-type-with-event-format --no-dry-run ``` If everything went well, then your terminal should have an output like this: ```sh:Terminal output ❯ sanity migration run replace-event-type-with-event-format --no-dry-run ? This migration will run on the production dataset in your-project-id project. Are you sure? Yes ✔ Migration "replace-event-type-with-event-format" completed. Project id: uxqfcg2d Dataset: production 179 documents processed. 179 mutations generated. 1 transactions committed. ``` This tells you that you have migrated 179 documents with 179 mutations, and it was all done with one transaction (that is one API request). In other words, it happened almost instantly for all these documents and anyone who had been in the Studio while you ran this. ![Missing alt text](https://cdn.sanity.io/images/3do82whm/next/1b2b8585295d5e7ad4b117492854094678ba3b00-2056x1300.png) ## Verifying the content migration Run the validation command again to see if there is content for the **Event format** field. 1. **Run** the following to confirm that the migration was successful ```sh # in apps/studio pnpm dlx sanity@latest documents validate -y ``` You should see no more validation errors: ```sh:Terminal output ❯ sanity documents validate -y ✔ Loaded workspace 'default' using project 'uxqfcg2d' and dataset 'production' (1.8s) ✔ Downloaded 457 documents (0.3s) ✔ Checked all references (0.0s) ✔ Validated 444 documents (3.4s) Validation results: ✔ Valid: 444 documents ✖ Errors: 0 documents, 0 errors ⚠ Warnings: 0 documents, 0 warnings ```