Im a hobby programmer exploring the free version of the new headless CMS sanity (www.sanity.io).
Bumping into a problem when trying to upload / import data into my project: Is there a way to import data from a csv file? Example from docs only explain json files: https://www.sanity.io/docs/content-studio/importing-data
Instead of explaining my own project, let me use the bundled movie studio as an example: Say that I would like to add a layer of information being which Film Studio made the movies. I have a CSV file with a list of studios, with columns being Name, Country, webpage, CEO, Movies. Where the final is an array with name of movies from that studio.I would like to import this CSV to create a new content type being studio, where the list of studios is populated, and where the movie array is references, not text.
Can anyone help me understand how I should go about doing hit?
There is currently no way to import data directly from a CSV file to Sanity. Still, achieving what you want is pretty straight forward. Briefly, this is want you'll want to do:
Say your CSV file named studios.csv
looks something like this:
NAME,WEBPAGE,MOVIES
Paramount,paramountstudios.com,Ghost in the Shell;Arrival
DreamWorks,dreamworksstudios.com,Ghost in the Shell;Minority Report;Transformers
The below code uses csv-parser, but it should still serve as an example if you want to use some other package for gobbling CSV.
const csv = require('csv-parser')
const fs = require('fs')
const sanityClient = require('@sanity/client')
const client = sanityClient({
projectId: 'my-project-id',
dataset: 'my-dataset',
useCdn: false
})
function appendToFile(document) {
const docAsNewLineJson = `${JSON.stringify(document)}\n`
fs.appendFileSync('ready-for-import.ndjson', docAsNewLineJson, {flag: 'a+'})
}
function moviesByTitles(titles) {
return client.fetch('*[_type == "movie" && title in $titles]', {titles: titles})
}
fs.createReadStream('studios.csv')
.pipe(csv())
.on('data', data => {
// Assuming movie titles are semi-colon separated
const titles = data.MOVIES.split(';')
// Fetch movies with these titles
moviesByTitles(titles).then(movies => {
// Build a Sanity document which matches your Studio type
const document = {
_type: 'studio',
name: data.NAME,
webPage: data.WEBPAGE,
movies: movies.map(movie => {
return {
_ref: movie._id,
_type: 'reference'
}
})
}
// Append the document to a file for later import
appendToFile(document)
)}
})
You'll end up with the file ready-for-import.ndjson
containing Sanity documents ready for import, so now you can simply:
sanity dataset import ready-for-import.ndjson <my-dataset>
It might prove useful to include an _id
field with a unique, non-random value on each studio, e.g. studio_${data.NAME.toLowerCase().replace(' ', '-')}
. This will allow you to import your documents multiple times (using the --replace
flag), without getting duplicates.