Data import & export

How to import Excel and CSV data into Odoo without duplicates

Prepare a clean spreadsheet, test a small contact import, and update the same records using External IDs. Use the export tool to learn the field names in your own database.

By OdooMatrix Published Updated 7 min read

At a glance

Import into the correct app, map every column, and run Test before Import. Keep a stable, unique External ID for each record so later imports can update it. Rehearse on a test database and take a backup before a production import.

1. Prepare a test database and a small file

Odoo supports Excel .xlsx and CSV .csv imports for many business objects, including contacts and products. The available fields depend on installed apps and customizations.

Start with two or three fictitious contacts in a test copy. Have permission to create or update the target records, and keep the original spreadsheet unchanged. See the backup and restore guide before importing live business data.

An import has lasting effects

Odoo’s documentation warns that imports cannot simply be undone. Test validates the file; it does not create a recovery copy of your database. Keep a backup and an import log.

2. Export a sample to discover the right fields

  1. Open Contacts and switch to list view.
  2. Select one representative contact, then choose Actions → Export.
  3. Enable Updatable fields only when preparing a file you intend to import back.
  4. Add the fields you need, including External ID when updating existing records. Review the selected field list; the switch filters available fields but does not remove fields already selected.
  5. Choose Excel or CSV and click Export.

Use this file to see the field labels and structure for your database. Some older versions use different export wording. Import templates are also offered for common objects in the import screen.

Exporting contacts is not a full database backup. An export only contains the records and fields you selected.

3. Create a clean contact import file

Use one header row and one record per row. Here is an illustrative CSV with fictitious contacts and reserved example email addresses:

CSV · sample contact import
External ID,Name,Email
contact_demo_1001,Alex Example,alex@example.com
contact_demo_1002,Sam Example,sam@example.com

Create this as a CSV or enter the three columns in an Excel workbook. Use unique identifiers for your own records; these demo identifiers are for a test database.

  • Preserve identifiers: format codes and phone numbers as text when leading zeros matter.
  • Use consistent dates: for CSV dates, prefer YYYY-MM-DD and check Odoo’s detected Date Format.
  • Check numbers: review decimal and thousands separators before importing prices or amounts.
  • Keep the header simple: remove merged cells, subtotal rows, notes, and extra title rows.
  • Check empty cells: an explicitly empty imported field can clear a value. Omit a field you do not intend to update.

External IDs must be unique across Odoo objects. A prefix such as contact_ or product_ helps prevent collisions between imports from different source tables.

4. Upload the file and map each column

  1. Open the target record list, such as Contacts.
  2. Open the action menu and choose Import records.
  3. Click Upload Data File and select your file.
  4. For CSV, inspect the preview and Formatting options. If all values appear in one column, correct the field separator before continuing.
  5. Map each File Column to the intended Odoo Field.

On small screens, scroll the table sideways to see every column.

Mapping for the example file
File columnOdoo fieldPurpose
External IDExternal IDIdentify this record on future imports.
NameNameSet the contact’s displayed name.
EmailEmailSet the contact’s email address.

Review every mapping even if Odoo selected it automatically. If a field is absent from the suggestions, the documentation notes that Odoo infers types from the first ten rows; the advanced relation-field option can reveal additional fields. Also check that the app defining the field is installed and your account has the required access.

5. Test the small batch, then import it

  1. Click Test.
  2. Read every error and fix the spreadsheet or mapping. Do not import a larger file to work around a failed test.
  3. Run Test again after changes.
  4. Click Import when the small batch validates.
  5. Return to Contacts, find both example contacts, and open them to verify their names and email addresses.

Expected: the two intended contacts exist once each, and their fields match the file. Check the actual records rather than relying only on a success message.

After a successful rehearsal, process the production file in manageable batches. Keep the file version, row count, date, operator, and result together so errors can be traced.

6. Update the same records without duplicating them

Keep each record’s original External ID. To change only Alex’s email in the example, import:

CSV · update by External ID
External ID,Email
contact_demo_1001,alex.updated@example.com
  1. Use the same target object, Contacts, and map External ID and Email.
  2. Run Test, then Import in the test database.
  3. Open the original Alex contact and check the changed email.
  4. Confirm that the number of example contacts is still two.

Odoo uses the identifier to decide whether to update an existing record or create one. A changed or unfamiliar External ID can create a new record. A matching name or email alone is not a substitute for a stable identifier in this workflow.

For records that already exist in Odoo, export their identifiers first. Do not invent new IDs and expect Odoo to match the old records automatically. Database IDs and External IDs are different identifiers; do not carry raw database IDs between unrelated databases.

7. Import related records in the right order

A customer on an order is a relation to another record. Import the related contacts or products first, then reference them from the dependent records.

The documented pattern is Field/External ID. For example, a relation to a customer can be mapped using that customer’s External ID. Use the actual relation label from your own export or field selector.

Matching by a name can be ambiguous when two records share it. External IDs make the relationship explicit. Order lines, taxes, units of measure, and multi-company data require their own mapping checks; do not assume the three-column contact example is a template for accounting entries or stock quantities.

8. Fix the common import problems

Odoo cannot find a related record

Import the related object first and check the exact External ID. Verify that the current company and your user can access it.

Dates or prices are interpreted incorrectly

Inspect CSV Formatting, date format, and decimal separators. In Excel, use genuine date cells. Test a row with an unambiguous date and verify the saved value.

The import times out

Use smaller batches, as Odoo’s documentation recommends, and keep the same identifiers across the batches.

A later import created duplicates

Check whether External ID was present, mapped, and unchanged. Stop further imports and inspect the affected records before attempting cleanup.

9. Complete the import checklist

  • The correct object and company are selected.
  • A backup and a successful test-copy rehearsal exist.
  • Every row has a stable, unique identifier where updates are needed.
  • Dates, numbers, empty cells, and related-record mappings were checked.
  • Test succeeds before Import.
  • Record counts and sample values match after importing and updating.

10. Frequently asked questions

Can I import an Excel file directly?

Yes. Odoo documents .xlsx and CSV imports. CSV exposes separator and date-format options; Excel uses the workbook’s cell values and types.

Will Odoo identify duplicates using the contact name?

For the repeatable update workflow in this guide, use the existing External ID. Names may repeat and are not a reliable replacement for an identifier.

Can I undo an import with one button?

Odoo warns that imports are permanent. Rehearse on a copy and take a backup before a live import; do not treat Test as an undo mechanism.

11. Related articles and next steps

Menu labels and available actions can vary with your Odoo version, installed apps, and permissions.

Continue learning

Need help with your Odoo setup?

Describe the version, hosting, and workflow you want to improve. Email OdooMatrix to discuss the next step.

← Back to all articles