Data import with a human in the loop: staging table and row review

Why data belongs in a staging table first, how rows are reviewed and why cleaning before import saves more than fixing afterwards.

7 min read ERP rollout and operations

A colleague in sales sends an Excel file with customers, purchasing sends a list of articles, and the shop delivers an export of orders. Someone maps the columns in the Odoo import assistant, clicks "Import", and the data is in the system. The problem only shows up days later: duplicate contacts, articles with the wrong unit, prices in the wrong field. Then the correction begins in the live system, record by record, with follow-up questions to the departments. That costs more time than a check before writing would have cost, and some errors are never noticed at all.

This article shows how you can split an import into three steps: load the data into a staging table, review it row by row, and only then write it to Odoo.

Why the One-Click Import Reaches Its Limit

A direct import is acceptable when the file is small, the columns are unambiguous, and a mistake is easy to undo. It becomes risky as soon as one of these conditions is missing:

  • The source comes from a legacy system or from Excel, where every user has named and filled columns differently.
  • The import creates links between records, such as customer to order or product to supplier.
  • The data flows into areas where corrections are difficult, such as posted documents.
  • The import recurs, for example daily or monthly.

Decision rule: If a wrong record could only be fixed by manual work in the live system, an intermediate stage belongs in front of it.

The Staging Table: Let Data Arrive Without Using It

A staging table is a store that takes in the raw data of the file without creating any Odoo master data or documents. Each row of the file becomes a row in the table, supplemented by a status, an error note, and a reference to the source file.

An example from a shop integration: a Shopify, Shopware, or WooCommerce export delivers products, some of which already exist in Odoo. If they land in the staging table first, you can see before writing which article numbers are already taken, which variants are missing, and where prices remain empty.

What the staging table should contain at a minimum:

  1. the original values of each row, unchanged
  2. the assigned target fields in Odoo
  3. a status per row, for example "new", "reviewed", "rejected", "written"
  4. a note explaining why a row stands out
  5. the origin: which file, which run

This keeps every row traceable, even weeks later.

Column Mapping: The Part an Agent May Prepare

Mapping columns to fields is tedious and error-prone. "Bezeichnung", "Name", "Artikeltext", and "Produkt" can all mean the same target field, and "Preis" can be net or gross. This is where software can do the groundwork.

In Simplify-ERP, this step works as follows: an agent maps the columns of a file to the fields of a staging table, a human reviews the rows, and code then writes them to Odoo. The import learns column aliases from earlier imports along the way. The mapping of "Artikeltext" to "Produktname" therefore does not have to be explained again on the next run. The division of tasks is the real point: the agent proposes, the human decides, deterministic code writes.

This also applies if you use a different tool. What matters is that a suggestion, whether it comes from a rule or an AI model, never flows directly into the master data.

Check question: For every column, is there a documented answer to "Which Odoo field is this, in which unit, and in which format?"

Row Review: What the Human Sees and Decides

A review across hundreds of rows only works if the view is sorted by anomalies. Do not check every row with equal thoroughness; instead, have the exceptions shown first:

  • Required fields empty
  • Possible duplicates, such as the same company name with a different spelling
  • References to records that do not exist in Odoo (category, supplier, tax)
  • Values outside the usual range, such as a price of zero or a negative quantity
  • Rows that would overwrite an existing record

For each row, the reviewer has three options: approve, correct, or reject. Rejected rows stay in the table with a reason. This matters for the feedback to the department: "We did not take over these rows, and this is why."

Decision rule: The person who reviews knows the data. For customers, that is sales; for articles, purchasing or product maintenance; for posting data, accounting. IT provides the tool but does not judge the content.

Writing to Odoo: Dry Run, Protection of Existing Data, Repeatability

Only after approval does a defined step write the rows into the target models. Three properties make this step safe:

  1. Dry run: It shows what would be written without writing anything. In Simplify-ERP, a dry run writes nothing.
  2. Protection of posted data: Posted documents are never overwritten. For imported incoming invoices, for example from sevDesk, the same principle applies: one-way and repeatable, with assignment of SKR accounts and taxes.
  3. Repeatability: A second run with the same file must not create duplicate records. This requires a stable key for each row, such as the article number or an external document number.

For article numbers, a rule for new records is worthwhile: Simplify-ERP assigns them sequentially, starting from the highest existing number. That way, newly imported articles do not collide with existing ones.

Clean Up Before the Import, Not After

The staging table does not replace data cleansing; it makes the need visible. The more you clarify in the source before the import, the shorter the row review becomes. Typical points:

  • Merge duplicates in the source
  • Standardize units and currencies
  • Convert free-text fields that are really selection values (country, payment term) into a fixed list
  • Name formulas from spreadsheets as rules: if a price in Excel is calculated from purchase price plus markup, the markup belongs in the ERP as a rule and not as a result in a price field

Examples from Day-to-Day Operations

Shop integration: Before the first synchronization, you import the existing shop catalog into the staging table. You clarify which system holds the master product data, and you reject rows that are already correctly maintained in Odoo.

Version upgrade: During an upgrade, data is often transferred to a new instance. The same idea helps here: copy in batches, map relations, and have a human decide conflicts. When taking over existing installations, Simplify-ERP copies data in batches via XML-RPC (an interface through which two Odoo instances exchange data) with relation mapping and an assistant for conflicts.

AI automation without code: When an agent reads data from documents or emails, such as contact details from business cards, the result is a suggestion. People should confirm it before it is saved. The exception is values for which you deliberately set a confidence threshold and whose consequences of error are minor.

Enterprise-wide search: Anyone who builds a search index from Odoo data quickly notices how poorly maintained master data degrades search results. A reviewed intermediate stage before the import improves the foundation for every later analysis.

Checklist: Plan an Import with a Review Step

  1. Which source, which target model, how often does the import recur?
  2. Who is responsible for the review from a subject-matter perspective, and how much time have they scheduled?
  3. Which columns are unambiguous, and which need a mapping rule?
  4. Which key identifies a row, so that a second run duplicates nothing?
  5. Which anomalies should be flagged automatically?
  6. Which records must never be overwritten?
  7. Is there a dry run, and who evaluates it?
  8. How does the feedback about rejected rows reach the department?
  9. Where is the source file stored after the run, and how long is the staging table kept?

Your Next Step

Take the last import that caused rework in your company. Answer one question about it today: at which point could a person have seen the faulty rows before they were in Odoo, and who would have been responsible? Write the answer into your import planning as a review step with a named owner.

All knowledge articles