导入报告只告诉你 URL key for specified store already exists,但后台搜索 URL Key 又找不到重复商品。真正冲突的是某个 Store 下的最终 request_path,占用者可能不是另一个商品。

先把失败范围缩到一行

  1. 复制原 CSV,只保留表头和一个失败 SKU;
  2. 在导入页面选择 Check Data,不立即 Import;
  3. 记录导入行为、Store View code、SKU、url_key、categories 和 product_websites。

如果单行通过,冲突来自同一 CSV 内两行生成相同路径;如果单行仍失败,继续查数据库。

计算它想生成的 request_path

假设 url_key 为 red-shirt,后缀为 .html,最直接的候选是 red-shirt.html。启用“Use Categories Path for Product URLs”、多 Store 覆盖或扩展后,还可能生成分类路径。先读取后缀与 Store 配置:

bin/magento config:show catalog/seo/product_url_suffix
bin/magento config:show catalog/seo/product_use_categories

在准确 Store 查询占用者

SELECT url_rewrite_id, entity_type, entity_id,
       request_path, target_path, redirect_type,
       store_id, is_autogenerated, metadata
FROM url_rewrite
WHERE store_id = 1
  AND request_path IN ('red-shirt', 'red-shirt.html')
ORDER BY request_path, url_rewrite_id;

entity_type=product 时,用 entity_id 查 SKU;category 则查分类;custom 记录可能来自旧跳转或扩展。Store ID 不同通常不冲突,所以不能忽略范围。

SELECT entity_id, sku
FROM catalog_product_entity
WHERE entity_id IN (123, 456);

没有精确记录,再查同一目标和大小写

SELECT url_rewrite_id, entity_type, entity_id,
       request_path, target_path, store_id
FROM url_rewrite
WHERE store_id = 1
  AND (LOWER(request_path) = LOWER('red-shirt.html')
       OR target_path = 'catalog/product/view/id/123');

数据库排序规则可能不区分大小写;Web Server 和 CDN 路径处理又可能区分。不要用只改变大小写的 URL Key 解决冲突。

按占用类型决定处理方式

  • 另一个有效商品:为新商品选择不同且有意义的 URL Key;
  • 旧商品需要迁移:先确定新旧 canonical,再保留精确 301;
  • 分类占用:不要让商品和分类争同一路径,重新规划其中一个 slug;
  • 确认无主的残留自动记录:先导出该记录与关联实体,在预发布删除并重新保存目标商品验证。

不要把整个 url_rewrite 表清空,也不要直接插入一条新 rewrite。核心会在保存实体时重新生成,手工记录很容易在下次更新后再次冲突。

重导前做两个检查

# CSV 中检查重复 url_key(示意,按实际列号调整)
awk -F',' 'NR>1 {print $5}' products.csv | sort | uniq -d

# 备份待改的 rewrite
mysqldump DB_NAME url_rewrite   --where="store_id=1 AND request_path='red-shirt.html'"   > /tmp/red-shirt-rewrite.sql

重新导入成功后,请求新 URL 应返回 200;旧 URL 如果存在历史流量,应只跳转一次到新地址;canonical 与 Sitemap 也要使用最终路径。