Import a customer's spreadsheet
Preview a CSV or Excel file, confirm the column mapping, run a dry run, then write the rows, with a report of every row that failed.
Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.
Stability The promise an interface ships with.
- Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
- Beta Usable in production; may change before it becomes stable.
- Experimental May change or go away; needs an explicit opt-in in main.yaml.
A customer uploads a spreadsheet of contacts. You preview the first rows, confirm which column is which, check a dry run, and write the rows. Nothing is written until the mapping is confirmed. It takes about 25 minutes.
You need
- A MainSDK app with a
dbmodel for the rows you import (for examplecontacts). - A schema for the row, with a unique key such as
email. - An upload, from
files.
1. Declare the import limits
imports:
inline-max: 5MB
max-rows: 10000002. Preview the file
"use server";
import { imports } from "mainsdk";
import type { FileRef } from "mainsdk/files";
import { s } from "mainsdk/schema";
const Contact = s.object({ email: s.string(), name: s.string() });
export async function previewContacts(file: FileRef) {
return imports.preview(file, { schema: Contact, key: "email" });
}The preview returns the columns, the first 20 rows, a suggested mapping and missing, the required fields no column maps to. Show these to the person.
3. Dry run with the confirmed mapping
import { imports } from "mainsdk";
import type { FileRef } from "mainsdk/files";
import { s } from "mainsdk/schema";
const Contact = s.object({ email: s.string(), name: s.string() });
declare const file: FileRef; // the upload
const run = await imports.file(file, {
schema: Contact, key: "email", into: "contacts",
mapping: { "E-mail": "email", "Full name": "name", "Company": null }, // null ignores a column
dryRun: true,
});
console.log(run.counts, run.report);counts shows what would be inserted, updated, unchanged or failed. report is a CSV of the failed rows.
4. Write the rows
Run the same call without dryRun. The mapping you pass is the confirmation. Set maxErrors if a few bad rows should not stop the run, for example maxErrors: "2%".
Check it worked
run.stateiscompleted, andcounts.inserted + counts.updated + counts.unchangedequals the rows you expect.- Running step 4 a second time writes nothing new. The default idempotency key is the file, target, key and mapping together.
- Open
run.reportand find the rows that failed.
If it fails
MAIN-IMPORT-0003: a required field has no column. Map it, or fix the header in the file.MAIN-IMPORT-0005: failed rows passedmaxErrors. Fix the rows in the report and run again.MAIN-IMPORT-0001: the file is not CSV, XLSX, JSON or NDJSON in UTF-8. Save it again.
Prompt for your coding agent
Add a spreadsheet import for contacts using MainSDK's
importsinterface. Preview the upload, show the suggested mapping, require the person to confirm it, run a dry run, then write the rows with a report of failed rows.
Was this page helpful?