Back to the blog Business Apps

CRM Data Import Checklist: How to Test a Self-Hosted CRM Before You Move Your Records

A successful CSV upload does not prove a CRM migration is safe. Use this checklist to test field mapping, duplicate rules, ownership, relationships, error handling, re-imports, permissions and rollback evidence before moving production records.

Operations lead reviewing CRM migration test results, source field mappings and a data import checklist

Why import quality matters more than a successful first upload

An import button is not a migration plan. A first upload can appear successful while silently creating duplicate contacts, assigning records to the wrong team, attaching a deal to the wrong organization, or discarding rows that fail validation.

Evaluate import capability as a control system. You need to know what the application creates, updates, rejects and reports; whether you can correct failures; and whether a repeat run is safe. The relevant question is not “Can it import CSV?” but “Can we produce trustworthy records from our real source data, repeatably?”

Different CRMs implement these controls differently. For example, EspoCRM documents Create Only, Create & Update and Update Only import modes. Its update-capable modes require the operator to choose fields that identify an existing record. That choice is a data-governance decision, not a technical default. See the [EspoCRM Import documentation](https://docs.espocrm.com/administration/import/).

  • Do not approve a CRM based only on a clean demo file.
  • Test with the same data types, inconsistencies and relationships found in the production export.
  • Record every configuration decision used in each test run.
  • Define success as accurate, usable records with explainable exceptions.
Why import quality matters more than a successful first upload

Start with an inventory of the source data

Create an inventory before mapping a single column. Spreadsheets and outgoing CRMs commonly hold related information in separate tabs, modules, free-text notes and file stores. If the inventory only counts contacts, the migration can look complete while losing sales context, ownership or operational history.

For each source table or export, identify its business purpose, record count, primary identifier, current owner, data steward, destination entity and relationship dependencies. Mark which data is essential on day one and which can be deferred or archived outside the CRM.

Include activities only after confirming that the destination model supports the relevant records and panels. In EspoCRM, for example, available Activities, History and Tasks panels depend on the configured entity type. Do not assume that every custom entity will expose the same related information as a person or organization record. See the [EspoCRM Entity Manager documentation](https://docs.espocrm.com/administration/entity-manager/).

  • Core records: people, organizations, leads, deals or equivalent entities.
  • Relationships: contact-to-organization, deal-to-contact, parent-child records and any many-to-many links.
  • Operational context: notes, calls, meetings, tasks, emails and history, where required.
  • Files: attachments, documents, file paths and links to external repositories.
  • Configuration data: custom fields, enumerated values, tags, teams, owners and statuses.
  • Source identifiers: IDs from the spreadsheet or previous system for every entity.
Start with an inventory of the source data

Define the destination data model before mapping fields

Field mapping should follow a destination model that has been deliberately agreed, not a desire to preserve every source column. Decide which destination entities will exist, which fields are required, which fields are custom, which values are controlled lists, and which information should remain outside the CRM.

For every source field, select one outcome: map directly, transform, split, combine, place in a controlled custom field, retain in an archive, or exclude. Document the rationale. A free-text “status” column, for example, should not be mapped into a restricted status field until its distinct source values have been reviewed and normalized.

Check import eligibility at the field level. SuiteCRM’s Studio documentation describes configuration for fields and relationships, including whether fields are allowed, disallowed or required for Import Wizard imports. It also identifies field type, auditing and duplicate-merge settings as field properties. The exact controls vary by CRM, so validate the target application rather than inferring them from another product. See the [SuiteCRM Studio documentation](https://pre-release.docs.suitecrm.com/admin/administration-panel/studio/).

  • Destination entity and field name.
  • Source table, column and source data type.
  • Transformation rule and permitted values.
  • Required, optional, sensitive or read-only status.
  • Import eligibility and default behavior.
  • Owner of the mapping decision and test result.

Build a representative test import instead of using a cleaned-up sample

A polished sample proves only that polished data can be imported. Build a small, representative test dataset from copies of real records, with sensitive values protected as needed. Preserve the problems your production data actually contains so that the test exposes how the importer behaves.

Include both ordinary records and deliberate edge cases. Test blank required values, incompatible values for controlled lists, duplicate names, duplicate email addresses, repeated source IDs, inconsistent phone formats, multi-value fields, punctuation, non-ASCII characters and dates written in more than one style.

Validation failures are valuable evidence. EspoCRM documents that a row failing validation does not create a record, with incompatible enum values and empty values for a non-empty enum among its examples. Your test should confirm the equivalent behavior in the CRM you are evaluating, including what happens to valid fields on a partially invalid row. See the [EspoCRM Import documentation](https://docs.espocrm.com/administration/import/).

  • Use a known record count for every test file.
  • Label the test records so they can be found and inspected later.
  • Keep an untouched copy of the original test extract.
  • Include known-good rows, known-bad rows and intentionally ambiguous rows.
  • Do not substitute production values with unrealistically uniform placeholders.

Test the decisions that create bad CRM data: duplicates, missing values, formatting and ownership

Duplicate control starts with an explicit matching policy. Decide which source identifiers are authoritative, whether email is unique enough for your use case, and how the CRM should treat a match on one field but not another. Record the exact matching fields selected for every run.

Stable source identifiers are particularly important for correction cycles. Odoo documents that consistent External IDs can support repeated imports without creating duplicates, while changing or removing an External ID can result in a new record rather than an update. Whether your chosen CRM uses External IDs or another identifier mechanism, verify that its identifier survives re-import exactly as expected. See the [Odoo export and import documentation](https://www.odoo.com/documentation/18.0/applications/essentials/export_import_data.html).

Do not trust automatic date detection. Odoo notes that date formats can be misrecognized, including day-month inversions, and recommends checking or setting an ISO 8601 format. Put ambiguous dates such as 03/04/2024 in the test file and inspect the saved value, not only the import preview.

Ownership requires the same scrutiny. EspoCRM can apply defaults, including Assigned User and Teams, to new and updated records during import. Test whether the source owner is preserved, translated, replaced by a default or left unset. Then decide which behavior is acceptable for each entity. See the [EspoCRM Import documentation](https://docs.espocrm.com/administration/import/).

  • Create a record with an existing source ID and changed non-key data; test the intended update path.
  • Create two records with similar names but different IDs; ensure they do not merge accidentally.
  • Test blank fields in an update file to learn whether they clear existing values, are ignored or fail validation.
  • Test date, number, currency, phone and multi-select formats.
  • Test a record whose original owner no longer exists in the destination.
  • Inspect owner and team values after both create and update runs.

Verify relationships and history: contacts, organizations, deals, notes, tasks and attachments

Relationship accuracy is often the difference between a useful CRM and a directory of disconnected records. Create test cases where one organization has several contacts, one deal has several related people, and records share similar or identical display names. Check every relationship from both sides in the destination interface.

Import parent entities before child entities when the relationship depends on previously imported records. SuiteCRM instructs users to import Accounts before related Contacts so that the relationship can be established. Odoo likewise documents importing related objects first when relations are recreated through External IDs. See the [SuiteCRM Record Management documentation](https://docs.suitecrm.com/8.x/user/core-concepts/record-management/) and [Odoo export and import documentation](https://www.odoo.com/documentation/18.0/applications/essentials/export_import_data.html).

Avoid relying on names for relationship matching when ambiguity is possible. Odoo warns that, where multiple related records have the same name, data may link to the first matching record. Use stable identifiers for relationship fields when the destination supports them, and prove the result with deliberately ambiguous test records.

Attachments and activity history deserve separate acceptance tests. Confirm whether files are imported, linked, skipped or need a separate product-specific procedure. Do not assume that the CSV importer used for core records also imports attachments, notes, tasks or history. For any supported procedure, confirm that dates, authors, parent records and permissions are appropriate.

  • Import organizations or accounts before related contacts.
  • Import parent deals or cases before their dependent notes and activities where required by the model.
  • Use source IDs to connect records rather than display names where possible.
  • Inspect relationship counts and individual links in the application.
  • Open sample attachments and verify their intended record association.
  • Check activity dates, creators, assignees and visibility.

Check how the application reports rejected or changed records

An importer that reports only a final total is difficult to operate safely. Require evidence for each rejected row: its source row or identifier, the reason for failure and the values that were supplied. Also require a way to distinguish newly created records from updates and skipped rows.

EspoCRM provides an Errors panel that includes the failure reason, row index and row values, and can export failed rows to CSV for correction and re-import. SuiteCRM documentation similarly describes an Errors tab for review and correction before rerunning an import. Treat these as useful examples of the evidence to seek, not an assumption that every CRM exposes identical reports. See the [EspoCRM Import documentation](https://docs.espocrm.com/administration/import/) and [SuiteCRM Record Management documentation](https://docs.suitecrm.com/8.x/user/core-concepts/record-management/).

Run a test containing valid records, invalid records and update candidates. Reconcile the source count against created, updated, rejected and skipped outcomes. Any unexplained difference is a failed acceptance criterion.

  • Can you export failed rows for correction?
  • Does each error identify a source row or stable source ID?
  • Does the report explain the failure in operational terms?
  • Can you distinguish creates, updates, rejects and skips?
  • Can you save mapping and duplicate-check settings for a repeatable run?
  • Can you inspect the resulting records directly from the import report?

Test correction and re-import without multiplying records or overwriting trusted data unintentionally

The most important import test is usually the second one. Correct a limited set of rejected rows, then re-import the corrected file using the intended update mode and matching rules. Confirm that corrected records are created or updated once, that already successful records are not duplicated, and that unrelated fields remain trustworthy.

Separate create behavior from update behavior in your acceptance criteria. In EspoCRM, Create Only creates records, while Create & Update and Update Only use selected matching fields to find records for update. A production team must know which mode it will use for initial loading, error correction and later incremental updates. See the [EspoCRM Import documentation](https://docs.espocrm.com/administration/import/).

Test blank and changed values with care. A re-import may overwrite information edited after the first import, depending on the selected mode and mappings. Establish a cutover window, identify the system of record for each field during migration, and define whether post-import edits are protected, overwritten or reconciled manually.

Keep the stable source ID in every correction file. Do not alter it simply to make an error disappear; that can convert an intended update into a new record. Odoo documents this risk for External IDs. See the [Odoo export and import documentation](https://www.odoo.com/documentation/18.0/applications/essentials/export_import_data.html).

  • Run an initial import and record created IDs and source IDs.
  • Correct only failed rows and retain their original identifiers.
  • Re-import and compare record counts before and after.
  • Test a changed value on an existing record deliberately.
  • Test a blank value on an existing record deliberately.
  • Check whether fields edited in the CRM after the first load are preserved or overwritten as intended.

Frequently asked questions

What is the minimum safe test for a CRM data import?

Use a representative subset that includes real entity types, relationships, custom fields, duplicate candidates, missing values, invalid controlled-list values, varied date formats, ownership cases and corrected error rows. Then reconcile source rows against creates, updates, rejects and skips.

Should I import contacts before organizations or accounts?

Usually import the parent entity first when contacts must be linked to it during import. SuiteCRM documentation gives Accounts before related Contacts as an example. Test the dependency order required by your chosen CRM and its relationship model.

How do I prevent duplicates when I re-import corrected CRM data?

Keep a stable source identifier for every entity and use a documented matching rule. Test the exact update mode and matching fields used by the target CRM. Do not change or remove the identifier in correction files, because that can turn an intended update into a new record.

Can an import rollback replace a full backup?

No. Import-level revert functions may not reverse updates made to existing records. EspoCRM, for example, documents that Revert Import removes imported records but does not revert updates caused by the import. Take and verify a full backup before production migration, and rehearse restoration before relying on it. For EspoCRM, a full backup includes both application files and a database dump; see the [Backup and Restore documentation](https://docs.espocrm.com/administration/backup-and-restore/).

Why test imports with a non-administrator account?

The production operator may have different access rights from an administrator. In EspoCRM, regular users require Import access and are subject to role permissions, while administrators have full system access. Test importing, ownership reassignment and sensitive-field visibility using the actual intended role. See the [EspoCRM Import documentation](https://docs.espocrm.com/administration/import/) and [Role Management documentation](https://docs.espocrm.com/administration/roles-management/).

Sources and further reading

  1. Import — EspoCRM Documentation
  2. Backup and Restore — EspoCRM Documentation
  3. Role Management — EspoCRM Documentation
  4. Entity Manager — EspoCRM Documentation
  5. Export and import data — Odoo Documentation
  6. Record Management — SuiteCRM Documentation
  7. Studio — SuiteCRM Documentation
  8. Volumes — Docker Docs