Import Methods
| Method | Best For | Volume |
|---|
| CSV Import (UI) | Non-technical users | Up to 10,000 records |
| XML-RPC/JSON-RPC | Developers, automation | Unlimited |
| XML Data Files | Module seed data | Hundreds |
| Odoo Shell | One-off data fixes | Any |
CSV Import (UI)
Step 1: Get the Template
# Open the target model list view:
# Contacts → Favorites → Import Records
# Click "Import Template" to download a CSV with correct headers
# Template columns match Odoo field names:
# name, email, phone, street, city, state_id, country_id, zip
Step 2: Prepare Data
# CSV requirements:
# - UTF-8 encoding (not ANSI or Latin-1)
# - Date format: YYYY-MM-DD (not MM/DD/YYYY)
# - Decimals: use period (99.99 not 99,99)
# - Boolean: True/False or 1/0
# - Many2one: use name or External ID
# Country: "United States" or "base.us"
# - Many2many: comma-separated names
# Tags: "VIP,Wholesale,Priority"
# Common cleanup:
# - Remove empty rows
# - Remove duplicates on unique fields
# - Trim whitespace
# - Standardize country/state names
Step 3: Import
# 1. Click "Import Records" in list view
# 2. Upload CSV file
# 3. Map columns to Odoo fields (auto-mapped if headers match)
# 4. Check "Import Options":
# - Headers: first row is headers
# - Separator: comma (or semicolon for some locales)
# - Track history: log import in chatter
# 5. Click "Test" to validate
# 6. If no errors → click "Import"
# 7. Records created/updated
Update vs Create
# To UPDATE existing records (not create duplicates):
# Include an "id" column with External IDs:
# id, name, email
# __import__.partner_001, John Smith, [email protected]
# Odoo matches by External ID:
# - If ID exists → UPDATE the record
# - If ID doesn't exist → CREATE new record
# Or use a unique field for matching:
# Import Options → "Use first column as unique identifier"
Common Import Errors
| Error | Cause | Fix |
|---|
| "No matching record found" | Many2one value doesn't match | Use exact name or External ID |
| "Encoding error" | File not UTF-8 | Save as UTF-8 in Excel/text editor |
| "Duplicate entry" | Unique constraint violated | Remove duplicates or use update mode |
| "Invalid date" | Wrong date format | Use YYYY-MM-DD format |
| "Required field missing" | Empty cell in required column | Fill in all required fields |
| "Import hangs/timeout" | Too many records at once | Split into batches of 1,000-5,000 |
Export Data
# From any list view:
# 1. Select records (or select all)
# 2. Action → Export
# 3. Choose fields to export
# 4. Format: CSV or Excel (XLSX)
# 5. Option: "I want to update data" → includes External ID column
# Export all records:
# Select all → banner says "Select all X records" → click it
# Then export
Programmatic Import (API)
# For large imports or automation, use XML-RPC:
import xmlrpc.client
import csv
models = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/object')
with open('contacts.csv', 'r') as f:
reader = csv.DictReader(f)
batch = []
for row in reader:
batch.append({
'name': row['name'],
'email': row['email'],
'phone': row['phone'],
})
if len(batch) >= 100:
models.execute_kw(db, uid, pwd, 'res.partner', 'create', [batch])
batch = []
if batch: # Remaining
models.execute_kw(db, uid, pwd, 'res.partner', 'create', [batch])
Import Best Practices
- Always test first — use "Test" button before importing
- Import in order — parent records first (categories before products)
- Batch large imports — split into 1,000-5,000 record batches
- Backup before import — always backup the database first
- Use External IDs — enables update mode and prevents duplicates
- Clean data first — garbage in = garbage out
DeployMonkey
DeployMonkey's AI agent assists with data import — validating CSV files, mapping columns, identifying errors, and suggesting fixes before import. Large imports handled via API for reliability.