Getting Started

Choosing your unique identifier

Published · Last updated

The unique identifier is the field (or combination of fields) Super Speedy Imports uses to decide whether a row should UPDATE an existing post or INSERT a new one. Get this right and re-imports are clean. Get it wrong and every re-import creates duplicates.

In the import screen this lives in its own section at the top of the mapping form, headed “How should existing products be matched?” (the heading names your post type – “posts”, “pages”, and so on). You pick a ready-made option from the dropdown, and a plain-English line confirms the consequence: “Rows with the same SKU update the existing product. Rows with a new SKU create a new one.”

This is the single most important decision when setting up an import.

What it does

On every run, SSI’s match-existing stage looks at each CSV row and asks: “Does WordPress already have a post with this unique identifier value?”

  • Yes → store that post’s ID on the batch row → the later update-posts / update-postmeta stages will UPDATE that post.
  • No → leave the post_id blank → insert-posts / insert-postmeta will create a new post.

For the SQL behind this decision, and the checks that stop a run before a row can attach to the wrong item, see Unique identifier matching internals.

Without a unique identifier, every re-import would duplicate every row.

The default for products – SKU

For a WooCommerce product import the default match option is SKU. It compares the value in the CSV column you map to SKU with the _sku field WooCommerce stores on every product and variation:

"post_meta": {
    "_sku": "SKU",
    "_regular_price": "Regular_Price"
}

With this mapping, a row whose SKU cell is ABC-123 updates the product or variation whose stored SKU is ABC-123, whether that item was created in wp-admin, by WooCommerce’s own importer or by another import. A row whose SKU is on no item is new.

The SKU column must be mapped for SKU matching to work; an import that matches on SKU without mapping it does not run.

A row with a blank SKU is handled by the blank-identifier setting, Stop the import (the default) or Skip that row – see “What happens with a blank identifier” below.

Constraint: SKU values must be unique within the file. If two CSV rows share an identifier, the import stops once the file is loaded, before any post is written, and tells you which rows collide.

Identifiers are compared in full, however long they are. Two product URLs used as identifiers that differ only after their first 100 characters are two items. If a row cannot be staged for any reason, the import stops with Import aborted — N row(s) could not be staged for import., naming the row number and identifier, so no row is ever left out without a message.

Choosing a match option

The “How should existing products be matched?” dropdown offers the ready-made options that fit your post type. For a WooCommerce product import you get:

  • SKU (the default) – matches on _sku, the right choice for almost every store.
  • GTIN / UPC / EAN / ISBN – matches on the WooCommerce global unique ID (_global_unique_id), for catalogues keyed on a barcode rather than a SKU.

For posts and pages the default is Post title, with a Post title + category option for feeds where the same title appears under different sections. Whichever you pick, SSI matches each CSV row against the field stored items carry, so a re-import updates them instead of duplicating.

Post ID (every edition)

Every import type also offers Post ID (posts.ID). Choose it when your file carries WordPress post IDs from this site, such as a CSV downloaded from the Data tab. Pick the column that holds the IDs in Post ID CSV column.

  • A row whose ID belongs to a record of the import’s post type updates that record. For a product import, product variations count too.
  • A row whose ID matches nothing follows the import mode. Under Only update existing items it is skipped; under a mode that creates items, it creates a new record, which receives a new WordPress ID rather than the one in the file.
  • An ID must be a positive whole number written in plain digits, with no spaces, leading zeros, decimals or exponents. A row with any other value stops the import during load-csv with Import aborted — N row(s) have invalid Post IDs. and the rows named.

Use IDs from the same site only. The same number on another site is a different record.

Custom – matching on your own combination of fields (paid edition)

Choose Custom… to build the identifier yourself from any combination of post fields (Title, Slug), postmeta (SKU, GTIN) and taxonomies. Tick the fields that together identify a row; an item matches only when all of the chosen fields are equal. This is the composite case – for example SKU + colour + size, when the same SKU repeats across variants and no single field is unique on its own.

Every field you include must also be mapped in the import. If you include a taxonomy, the run must resolve terms (Full, Only update, Only insert or Re-sync taxonomies – not the “prices only” or “images only” modes).

The Custom builder is a paid-edition feature. The Lite edition matches on the ready-made options above.

Note: the identifier is always a preset or a Custom composite; a raw CSV column or a PHP function cannot be the identifier. An older import that matched that way needs a preset or the Custom composite builder instead.

What happens with a blank identifier

By default SSI treats a blank match value as a fatal data-quality issue. The matcher section carries the control for this – “If a row has a blank match value:” – with two choices: Stop the import so I can fix the file (the recommended default) or Skip that row and continue. Only an empty cell is blank: a cell holding 0 is a value, so a SKU of exactly 0 is an identifier like any other. On the default, any CSV row with a blank value in the configured identifier makes the import abort during load-csv:

Import aborted — 5 row(s) have a blank unique identifier.
Every row must have a non-empty value in column 'SKU'.

Row 12: blank value in unique identifier column 'SKU'
Row 47: blank value in unique identifier column 'SKU'
...

The abort is by design – silently inserting rows with blank identifiers would create posts that can’t be matched on the NEXT re-import, leading to duplicates forever. Fix the CSV (fill in the missing identifiers or remove the rows) and re-run.

Things to watch for

Changing the match option between runs

Matching compares each row with data the items on your site carry, not with anything an earlier option stored. Whether a run after a change updates your catalogue or duplicates it therefore depends on whether the existing items carry the field the NEW option matches on.

Switching is safe when the existing items carry the new field:

  • To SKU, GTIN / UPC / EAN / ISBN, or a single metadata field in Custom. Every item with that field stored matches, whichever option or tool created it. Switching from SKU to GTIN updates every product that has a GTIN stored.
  • To Post ID. Every item whose ID is in the file matches, provided the IDs come from this site.
  • To Post title, Post title + category, or a Custom combination of fields. Each run works out the combined value from the current values of the items of the import’s post type (for products, products and variations, in the trash or not) that share the first field (the title, for example) with a row in the file. An item matches when every field agrees.

Switching duplicates items, or skips their rows, when they do not carry the new field in the form the file holds:

  • The field is missing or different on the item. A product with no GTIN stored does not match on GTIN. A value with a trailing space, different leading zeros or (for a combination) different upper and lower case is a different value.
  • A taxonomy in a combination does not agree. Post title + category matches only an item whose current categories are exactly the ones the row resolves to; for a hierarchical taxonomy such as category, that means the deepest assigned categories.
  • A live item and a trashed item share the combined value. A combination finds items in the trash, which are restored, and product variations, as SKU does. When a live item and a trashed one (or two items) have the same combined value, the run stops with “matches more than one existing item” and names them; delete the trashed one permanently or add a field to the combination.

A row that matches nothing creates a new item in a mode that creates items, and is skipped under Only update existing items. With Delete missing items ticked, an item this import last wrote that no row matched is also deleted as missing.

Before the first run on a new option, use the Data tab to find items that lack the new field or share a value.

Trim whitespace in your CSV

SSI matches identifiers byte-for-byte. A SKU "ABC-123 " (trailing space) and "ABC-123" are different identifiers. Most spreadsheet exports preserve trailing whitespace; check your CSV.

Case sensitivity depends on your DB collation

abc-123 and ABC-123 may or may not match depending on whether your WordPress database uses a case-sensitive collation. Default WP collation (utf8mb4_unicode_520_ci) is case-insensitive, so they’ll match. Custom collations may not. When in doubt, normalise to one case in your CSV.

Post title, Post title + category and Custom combinations are always case-sensitive, whatever the collation: Blue Shirt and blue shirt are two different items.

The same rule applies inside one file: on a case-insensitive database, a file holding both ABC-123 and abc-123 has a duplicate identifier, and the import stops with Identifier 'ABC-123' appears on 2 rows. before anything is written.

SSI’s behaviour on duplicate identifiers within ONE CSV

If your CSV has two rows with the same identifier (a real data bug, but it happens), the import aborts at the end of load-csv, before any post is written. The message lists the colliding rows and, when it can find one, names the column that differs between them. That column is usually the one to add to a Custom… composite identifier; otherwise fix the file and re-run.

Summary checklist

  • ✓ Pick a field whose values are stable, unique, and present on every row.
  • ✓ If no single field is unique, use Custom… to combine several (e.g. SKU + colour + size) so the combination is unique.
  • ✓ Before changing the match option, check that the existing items carry the new field.
  • ✓ Trim whitespace and normalise case before importing.
  • ✓ Watch for the “blank unique identifier” abort on first run – fix the CSV, don’t bypass the check.

Check the stored data before you import

The Data tab finds records on your site that share or lack a matching value, such as two products with one SKU. Click Check existing data under the matching section of an import to run that check for the field the import matches on.

What’s next

  • Import modes and what each stage writes: what happens to a matched item and a new item in each mode.
  • Quick start – importing products: shows where this fits in the bigger setup flow.
  • How imports work – the stage pipeline: explains why match-existing runs WHEN it does and what depends on it.
  • Stage selection presets: lets you run just the matching+update flow without re-doing the full pipeline.
  • Fixing Slow WooCommerce Imports – the hub guide, including the fixes that work whichever importer you use.

Written for Super Speedy Imports 3.63.0.

Comments

▲
▼
1/1