Seed Accounts, Contacts, Cases, Contracts, and Products into lower Salesforce environments using SFDMU (Salesforce Data Move Utility).
SFDMU uses a single export.json config file to define which objects and fields to migrate. You can pull from a source org or from local CSV files. Objects are processed in dependency order automatically — parent records (Account) before children (Contact, Case, etc.).
your-sfdmu-project/
├── export.json # Migration config
├── Account.csv # Optional: seed data from CSV instead of org
├── Contact.csv
├── Case.csv
├── Contract.csv
└── Product2.csv
# Org-to-org (pull from source, push to target)
sf sfdmu run -s [email protected] -u [email protected]
# CSV-to-org (seed from local CSV files)
sf sfdmu run -s csvfile -u [email protected]
# Dry run (no changes made)
sf sfdmu run -s csvfile -u [email protected] --simulation
# Skip interactive prompts (CI/CD)
sf sfdmu run -s csvfile -u [email protected] --nopromptUse SFDMU to pull a controlled slice of prod data into local CSV files, then use those CSVs to seed sandboxes. This gives you a versioned, repeatable dataset you can check into source control.
Set --targetusername csvfile to write query results to local CSV files instead of another org.
sf sfdmu run -s [email protected] -u csvfile -p ./sfdmu-dataThis runs every query in your export.json against prod and writes the results as CSV files alongside it (Account.csv, Contact.csv, etc.).
Keep prod exports small and intentional. Use WHERE clauses and LIMIT to avoid pulling the entire org.
{
"query": "SELECT Name, Industry, Phone FROM Account WHERE CreatedDate = LAST_N_DAYS:90 LIMIT 50",
"operation": "Upsert",
"externalId": "Name"
}If the export contains PII, add updateWithMockData and mockFields (see Data Anonymization below) so sensitive values are replaced with fake data during the export.
sf sfdmu run -s csvfile -u [email protected] -p ./sfdmu-dataProduction ──(export to CSV)──► Local CSVs ──(commit to repo)──► Seed any sandbox
│
└── anonymize PII before committing
Heads up: Use
--canmodify(-c) if your source is a production org and SFDMU prompts for confirmation. The--simulationflag is your friend for the first run.
This export.json seeds five core objects with their required fields. Each object uses Upsert with a natural key so you can re-run safely without creating duplicates.
{
"$schema": "https://raw.githubusercontent.com/forcedotcom/SFDX-Data-Move-Utility/main/schemas/export.schema.json",
"excludeIdsFromCSVFiles": true,
"objects": [
{
"query": "SELECT Name, Industry, Phone, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry FROM Account WHERE Name LIKE 'Test%' LIMIT 50",
"operation": "Upsert",
"externalId": "Name"
},
{
"query": "SELECT FirstName, LastName, Email, Phone, AccountId, Title, MailingCity, MailingState FROM Contact WHERE Account.Name LIKE 'Test%' LIMIT 100",
"operation": "Upsert",
"externalId": "Email"
},
{
"query": "SELECT Subject, Status, Priority, Origin, ContactId, AccountId, Description FROM Case WHERE Account.Name LIKE 'Test%' LIMIT 100",
"operation": "Upsert",
"externalId": "Subject",
"master": false
},
{
"query": "SELECT ContractNumber, AccountId, Status, StartDate, ContractTerm FROM Contract WHERE Account.Name LIKE 'Test%' LIMIT 50",
"operation": "Upsert",
"externalId": "ContractNumber",
"master": false
},
{
"query": "SELECT Name, ProductCode, Family, IsActive, Description FROM Product2 WHERE IsActive = true LIMIT 50",
"operation": "Upsert",
"externalId": "ProductCode"
}
]
}The root parent — most other objects look up to it. Name works as a natural external ID for test data.
| Field | Why |
|---|---|
Name |
Required. Also our upsert key. |
Industry, Phone |
Common fields for realistic test data. |
Billing* |
Address fields — useful for geo-dependent logic. |
Child of Account via AccountId. SFDMU resolves the Account relationship automatically as long as Account is in the same migration.
| Field | Why |
|---|---|
FirstName, LastName |
Required (LastName is mandatory). |
Email |
Our upsert key — must be unique per contact. |
AccountId |
Links to parent Account. SFDMU handles the lookup. |
Child of both Account and Contact. master: false means only Cases linked to the migrated Accounts/Contacts are transferred.
| Field | Why |
|---|---|
Subject |
Our upsert key — keep unique per case. |
Status, Priority, Origin |
Required by default Case page layout / validation. |
ContactId, AccountId |
Relationships resolved from earlier objects. |
Child of Account. ContractNumber is auto-generated on insert but serves as our upsert key for re-runs.
| Field | Why |
|---|---|
ContractNumber |
Auto-number field, used as upsert key. |
AccountId |
Required parent lookup. |
Status, StartDate, ContractTerm |
Required fields for a valid Contract. |
Standalone — no parent dependency. Products are org-wide, not account-specific.
| Field | Why |
|---|---|
Name |
Required. |
ProductCode |
Our upsert key — must be unique per product. |
Family, IsActive |
Common classification fields. |
When using --sourceusername csvfile, place CSV files in the same directory as export.json. Column headers must match API field names. Use relationship notation for lookups.
Account.csv
Name,Industry,Phone,BillingCity,BillingState,BillingCountry
Test Acme Corp,Technology,415-555-0100,San Francisco,CA,US
Test Globex Inc,Manufacturing,312-555-0200,Chicago,IL,US
Test Initech LLC,Finance,212-555-0300,New York,NY,USContact.csv — use Account.Name to reference the parent:
FirstName,LastName,Email,Phone,Account.Name,Title
Jane,Doe,[email protected],415-555-0101,Test Acme Corp,VP Engineering
John,Smith,[email protected],312-555-0201,Test Globex Inc,Director of Ops
Alice,Park,[email protected],212-555-0301,Test Initech LLC,CFOCase.csv
Subject,Status,Priority,Origin,Account.Name,Contact.Email,Description
Test Billing Issue,New,High,Email,Test Acme Corp,[email protected],Monthly invoice discrepancy
Test Feature Request,New,Medium,Web,Test Globex Inc,[email protected],Request for API access
Test Login Problem,New,High,Phone,Test Initech LLC,[email protected],SSO not redirectingContract.csv
ContractNumber,Account.Name,Status,StartDate,ContractTerm
CON-0001,Test Acme Corp,Draft,2025-01-01,12
CON-0002,Test Globex Inc,Draft,2025-06-01,24
CON-0003,Test Initech LLC,Draft,2025-03-15,6Product2.csv
Name,ProductCode,Family,IsActive,Description
Test Widget Pro,WIDGET-PRO,Hardware,true,Standard widget unit
Test Cloud Suite,CLOUD-SUITE,Software,true,SaaS platform license
Test Support Plan,SUPPORT-PLAN,Services,true,24/7 premium supportWhen pulling from a production org, anonymize PII before landing it in sandboxes. Add mockFields and set updateWithMockData: true on the object.
{
"query": "SELECT FirstName, LastName, Email, Phone, AccountId FROM Contact",
"operation": "Upsert",
"externalId": "Email",
"updateWithMockData": true,
"mockFields": [
{ "name": "FirstName", "pattern": "first_name" },
{ "name": "LastName", "pattern": "last_name" },
{ "name": "Email", "pattern": "email" },
{ "name": "Phone", "pattern": "phone" }
]
}| Pattern | Output Example | Use For |
|---|---|---|
first_name |
"Maria" | First names |
last_name |
"Johnson" | Last names |
name / full_name |
"Alex Turner" | Full names |
email |
"[email protected]" | Email addresses |
phone |
"+1-555-0142" | Phone numbers |
city |
"Portland" | City names |
street |
"742 Evergreen Ter" | Street addresses |
zip |
"97201" | Postal codes |
country |
"United States" | Country names |
company_name |
"Acme Corp" | Company/Account names |
sentence |
"Lorem ipsum..." | Description fields |
url |
"https://example.com" | Website fields |
integer |
42 | Numeric fields |
c_seq_number('ACCT-', 1000, 1) → "ACCT-1000", "ACCT-1001", "ACCT-1002"
c_seq_date('2025-01-01', 'd') → "2025-01-01", "2025-01-02", "2025-01-03"
c_set_value('Test Account') → Sets every record to "Test Account"
{
"updateWithMockData": true,
"mockFields": [
{
"name": "all",
"pattern": "sentence",
"excludeNames": ["Email", "AccountId", "Status"]
}
]
}| Feature | What It Does | Docs |
|---|---|---|
deleteOldData |
Wipe target records before inserting — clean slate per run | ScriptObject |
simulationMode |
Dry run the entire migration without touching the target | Script Object |
useValuesMapping |
Transform field values during migration via ValueMapping.csv |
Record Transformation |
fieldMapping |
Map source field names to different target field names | ScriptObject |
sourceRecordsFilter |
Filter source records after query (SQL-like expressions) | ScriptObject |
objectSets |
Split migration into sequential phases for complex dependencies | Export.json Overview |
LIMIT in queries |
Control volume — start small, scale up | Built into SOQL |
allOrNone |
Fail the entire batch if any record errors — strict mode | Script Object |
excludedFields |
Drop specific fields from migration without editing the query | ScriptObject |
| Add-ons | Run custom JS before/after migration for transforms, validation | Advanced Examples |
- Order doesn't matter in the
objectsarray — SFDMU resolves dependency order automatically. master: falseon child objects ensures only records related to migrated parents are transferred. Without it, the query runs unrestricted.excludeIdsFromCSVFiles: trueat root level prevents Salesforce IDs in CSVs from being treated as real IDs in the target org.- Re-run safely:
Upsertwith a natural key means running the migration twice won't create duplicates. - Start with
--simulationto validate your config before writing to the target. - Relationship notation: In CSV files, use
Account.Name(notAccountId) to reference parent records by their external ID.
Sources: SFDMU Help Center · Basic Examples · Data Anonymization · ScriptObject Reference · CSV Examples