How to migrate data between schemas in Sanity without manual copying?
I understand your situation! You need to change the _type field from projects to uniprojects for existing documents. Unfortunately, the _type field is immutable in Sanity, meaning you cannot directly modify it through the Studio, the migration toolkit, or standard API mutations.
However, there's a reliable workaround using the export/import workflow with NDJSON files. Here's how to do it:
The Export-Modify-Import Approach
1. First, make sure your new schema is ready
Ensure your uniprojects schema is already defined in your Studio before starting. The documents need to validate against the new schema when you import them.
2. Export your dataset
sanity dataset export productionThis creates a production.tar.gz file containing all your data in NDJSON format.
3. Extract and modify the NDJSON file
Extract the tar.gz archive to access the data.ndjson file inside. Then, use a text editor or command-line tool to replace the _type value. With command-line tools:
# Extract the archive
tar -xzf production.tar.gz
# Replace _type in the NDJSON file
sed -i 's/"_type":"projects"/"_type":"uniprojects"/g' data.ndjsonOr you can use a script for more control:
const fs = require('fs');
const data = fs.readFileSync('data.ndjson', 'utf8');
const lines = data.split('\n');
const modified = lines.map(line => {
if (!line.trim()) return line;
const doc = JSON.parse(line);
if (doc._type === 'projects') {
doc._type = 'uniprojects';
}
return JSON.stringify(doc);
});
fs.writeFileSync('modified-data.ndjson', modified.join('\n'));4. Import the modified data
sanity dataset import modified-data.ndjson productionThis will import your documents with the new _type value. Since the _id values remain the same, Sanity will update the existing documents rather than creating duplicates.
Important Considerations
- Backup first: The export you just created serves as your backup, but consider keeping it safe before importing
- The
_typefield is truly immutable: Even the migration toolkit'sat('_type', set('uniprojects'))won't work because Sanity's underlying API prevents direct_typechanges - Document IDs are preserved: Your documents keep their original
_idvalues, so references and relationships remain intact - Test on a development dataset first: If you have a staging or development dataset, practice this workflow there before running it on production
Why Not Use Migrations?
While Sanity's migration toolkit with defineMigration is excellent for most schema changes (renaming fields, transforming content, etc.), it cannot modify the _type field because it's a protected system field. The export/import approach is the officially supported method for this specific use case.
This approach may seem manual, but it's actually quite fast and reliable for changing document types while preserving all your data and relationships!
Show original thread2 replies
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.