Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import CSV to sanity.io

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?

like image 542
Magnus Hillestad Avatar asked Sep 11 '25 04:09

Magnus Hillestad


1 Answers

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:

  1. Parse CSV file
  2. Structure incoming data to match you schema
  3. Write new documents to a newline-delimited JSON file
  4. Import that file to Sanity

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.

like image 84
thomax Avatar answered Sep 13 '25 18:09

thomax