asteria-migration.md 12 KB

Asteria(Magento 1)→ Bagisto 数据迁移说明

从旧站 Asteria(Magento 1.x)只读导入商品、用户、评论、订单到本店。源库以 as 为准(不要用 longyishop)。命令共用 Laravel 连接名 asteria,可分批、可断点续跑、可 --dry-run,重复执行不会重复插入。

推荐顺序: 需要清空现有商品时先 reset,再迁商品,再迁用户,再迁订单 / 评论。

php artisan migrate
php artisan catalog:reset --dry-run         # 先看会清哪些表
php artisan catalog:reset --force           # 清空现有商品,便于重新导入
php artisan products:migrate-asteria        # Magento 商品 → flexible_variant,SKU 与旧站一致
php artisan customers:migrate-asteria
php artisan orders:migrate-asteria
php artisan reviews:migrate-asteria --sync  # 或走队列,见下文

catalog:reset 会 TRUNCATE 商品及变体 / 库存 / 评论 / 购物车行 / 收藏,并把历史订单行的 product_id 置空(SKU 快照保留)。属性、分类、用户、订单头不删。也可跑 database/scripts/reset_catalog.sql。图片目录加 --purge-files


1. 前置:Asteria 数据库连接

.env 中配置只读 Magento 库(应用层只跑 SELECT):

ASTERIA_DB_HOST=127.0.0.1
ASTERIA_DB_PORT=3306
ASTERIA_DB_DATABASE=as
ASTERIA_DB_USERNAME=root
ASTERIA_DB_PASSWORD=
ASTERIA_DB_PREFIX=          # Magento 有表前缀时填写,例如 mag_
ASTERIA_DB_CHARSET=utf8
ASTERIA_MEDIA_BASE_URL=https://img.asteriahair.com/media/catalog/product
ASTERIA_STORE_MEDIA_URL=https://img.asteriahair.com/media/
ASTERIA_ATTRIBUTE_FAMILY=wigs
# 留空 = 挂到全部 Bagisto channel;只要部分站点再填 code,逗号分隔
ASTERIA_CHANNELS=
ASTERIA_LOCALES=

连接名默认 asteria,定义在 config/database.php。所有命令都支持 --connection= 覆盖。

跑迁移前确认 Bagisto 侧列已存在:

php artisan migrate
幂等列 迁移文件
products migrated_from_asteria_id(unique);SKU 仍唯一 database/migrations/2026_09_01_151700_add_asteria_migration_column_to_products_table.php
customers migrated_from_asteria_id(unique),另有 legacy_password database/migrations/2026_08_20_163200_add_asteria_migration_columns_to_customers_table.php
orders migrated_from_asteria_id(unique) database/migrations/2026_08_25_143200_add_asteria_migration_column_to_orders_table.php
product_reviews migrated_from_asteria_id(unique) 评论命令在缺列时会提示,也可交互自动 ALTER TABLE

商品白名单、变体 Option、图片 URL 前缀在 config/asteria.php(可用 ASTERIA_MEDIA_BASE_URLASTERIA_ATTRIBUTE_FAMILY 等覆盖)。


2. 商品 products:migrate-asteria

从 Magento 目录只读写入 Bagisto:include_eav_attributes 属性、flexible_variant 商品、图片 URL、库存、按名称匹配的分类、以及由 Custom Option 展开的变体。逻辑对齐 Asteria 的 shell/migrate_to_bagisto.php,落库方式对齐 catalog:sync(不再经 XLS)。

php artisan products:migrate-asteria
php artisan products:migrate-asteria --batch-size=50
php artisan products:migrate-asteria --sku=PC001
php artisan products:migrate-asteria --limit=5 --dry-run
php artisan products:migrate-asteria --attributes-only
php artisan products:migrate-asteria --products-only --no-index
php artisan products:migrate-asteria --reset-progress

源表:catalog_product_entity 及 EAV、catalog_product_entity_media_gallerycataloginventory_stock_itemcatalog_category_productcatalog_product_option*。只导入 Magento status=1(启用)且 SKU 非空的商品。

行为要点:

  • 属性:按 config/asteria.phpinclude_eav_attributes 创建 Bagisto 属性(select 带选项),并挂到属性族的 general 组。已存在的属性不改类型,只补缺失选项并保证在族里。若跑过 config:cache,改完配置后需要 php artisan config:clear
  • 商品类型一律 flexible_variant。属性族优先 wigs,没有则 variant_product / default
  • Channel:默认挂到 Bagisto 全部 channelproduct_channels),库存写到这些 channel 关联的全部 inventory_sourcesvalue_per_locale 属性按各 channel 的 locale 各写一份(内容相同);value_per_channel 按各 channel code 各写一份。只要部分站点:ASTERIA_CHANNELS=default,euconfig/asteria.phpchannels
  • Custom Option:drop_down / radio 作为变体维度(可用 variant_option_titles 白名单,或 skip_option_titles 排除),笛卡尔积写入 product_options / product_variants。图片不下载,写入 Magento 绝对 URL。
  • 分类:按 Bagisto 分类译名匹配,对不上的跳过(不自动建分类)。
  • 已有相同 migrated_from_asteria_id 或相同 SKU:更新(属性 / 图 / 库存 / 变体重建)。
  • 默认跑完会重建被改动商品的 price / flat(以及 elastic,若已开启)。大批量可加 --no-index,之后再索引。

进度缓存:migrate_asteria_products_last_id(30 天)。--sku= 不写进度。

catalog:sync 仍可从 storage/sync 的 CSV/XLS 导入,适合离线导出;连着 Asteria 库时用本命令。


3. 用户 customers:migrate-asteria

同步写入 Bagisto customers + addresses + 订阅(同步、无队列)。

php artisan customers:migrate-asteria
php artisan customers:migrate-asteria --batch-size=200
php artisan customers:migrate-asteria --dry-run
php artisan customers:migrate-asteria --reset-progress

源表:customer_entitycustomer_address_entity 及对应 EAV,以及可选的 newsletter_subscriber

行为要点:

  • 无效邮箱:跳过。
  • 已有相同 migrated_from_asteria_id 或相同邮箱(不区分大小写):关联,不覆盖姓名/密码,只补未导入的地址。
  • 新用户:写入 general 分组、默认 Channel;password 为随机 bcrypt,Magento 哈希放在 legacy_password。用户用旧密码登录成功后会自动升级为 bcrypt。
  • 手机号与现有用户冲突:新用户 phone 置空。
  • 地址按 addresses.additional.asteria_address_id 去重;街道换行压成 ,
  • 订阅:Magento newsletter_subscriber.subscriber_status = 1 为已订阅,写入 customers.subscribed_to_news_letter,并按邮箱幂等写入 subscribers_list。已退订(status=3 等)的注册用户会写成未订阅并保留 subscribers_list 记录;无账号的游客订阅只导入已订阅邮箱。无 newsletter_subscriber 表时跳过,不影响用户导入。重复执行会回填已迁用户的订阅状态。

进度缓存:migrate_asteria_customers_last_id(30 天)。


4. 评论 reviews:migrate-asteria

写入 product_reviews。默认按队列 review-migration 分批投递;--sync 则当场处理。

php artisan queue:work --queue=review-migration   # 非 --sync 时需要
php artisan reviews:migrate-asteria
php artisan reviews:migrate-asteria --batch-size=200
php artisan reviews:migrate-asteria --status=1     # 仅 Magento 已审核
php artisan reviews:migrate-asteria --sync
php artisan reviews:migrate-asteria --dry-run
php artisan reviews:migrate-asteria --reset-progress

--status:Magento status_id1=approved2=pending3=not-approved。不传则全部导入,状态映射为 Bagisto 的 approved / pending / disapproved

关联方式:

  • 商品:Magento catalog_product_entity.sku ↔ Bagisto products.sku。对不上的评论会跳过并打日志。
  • 用户:按邮箱挂 customer_id;没有则游客名(name)。
  • 图片:写入 Magento review_media_image 的 URL,后续再批量上 S3(不在本命令内下载文件)。

进度缓存:migrate_asteria_reviews_last_id(30 天)。


5. 订单 orders:migrate-asteria

同步写入订单头、商品行、账单/收货地址、支付方式。

php artisan orders:migrate-asteria
php artisan orders:migrate-asteria --batch-size=100
php artisan orders:migrate-asteria --dry-run
php artisan orders:migrate-asteria --reset-progress

源表:sales_flat_ordersales_flat_order_itemsales_flat_order_addresssales_flat_order_payment,以及可选的 mw_reward_point_order

会做:

  • 保留 Magento increment_idcreated_at,方便用户认历史单号。
  • 客户:先按 customers.migrated_from_asteria_id,再按邮箱;都没有则游客单(快照姓名/邮箱仍写入)。
  • 商品行:按订单行 SKU 对 Bagisto;对不上仍导入快照,product_id 为空。
  • 优惠券:写入 coupon_code 和订单/行折扣金额。不迁 Magento salesrule 规则本身,也不回写券使用次数。
  • 积分抵扣 / 赚取:mw_rewardpointmw_rewardpoint_discountmw_reward_point_orderreward_points_used / reward_points_amount / reward_points_earned。不迁客户积分余额。
  • 丢件险:Amasty Checkout Fees(amcheckoutfees_amount,费用名 insurance / Insurance for Lost)→ shipping_insurance_amount
  • 状态:completecompletedcanceledcanceledpending_payment / payment_review / pending_paypalpending_paymentholdedpending;其余常见状态原样对应,未知为 pending
  • 支付:paypal_express / paypal_standard / paypaluk_*paypal_standardcheckmomoneytransferklarna*klarnaafterpay* / clearpay*afterpay。原文写在 order_payment.additional.magento_method

不做: 发票、发货、退款;不扣库存;不触发下单邮件 / 礼品卡等 checkout.order.save.after 事件。

跳过规则:

  • 已有 migrated_from_asteria_id(幂等)。
  • Magento increment_id 已被 Bagisto 现网订单占用(避免覆盖新单)。
  • increment_id 为空。

进度缓存:migrate_asteria_orders_last_id(30 天)。


6. 共同约定

选项 含义
--batch-size 每批条数;商品默认 100,用户默认 500
--dry-run 只统计,不写库,也不更新进度
--reset-progress 从 ID=0 重新扫(仍幂等,已迁记录会 skip)
--connection 源库连接名,默认 asteria

中断后再次执行会从缓存的 last id 继续。换环境或确认要重扫时加 --reset-progress


7. 明确不迁的数据

后台管理员、收藏、客户积分余额、购物车 Quote、发票、发货单、退款单、Magento 分类树本身都不在这些命令范围内。商品只按名称挂到已有 Bagisto 分类。订单上的积分抵扣/赚取和丢件险金额会随 orders:migrate-asteria 写入。


8. 常见问题

连不上 Asteria: 检查 .envASTERIA_DB_*,以及 Magento 表前缀 ASTERIA_DB_PREFIX。源库必须是 as,不要配成 longyishop

MySQL 5.6 Unknown column 'generation_expression' Laravel 自带的 Schema::hasColumn() 会查 5.7 才有的 information_schema.columns.generation_expression。迁移脚本已改用 SHOW COLUMNS,可在 5.6 上跑。若 TablePlus 等客户端仍报这个错,是客户端自己在看表结构,与迁移无关。

提示缺列:php artisan migrate。评论列也可在命令交互里自动加。

评论一条都没有 / 大量 skip: 先确认 products:migrate-asteria 后 SKU 与 Magento 一致。

商品属性族找不到: 在 Bagisto 建好 wigs(或改 ASTERIA_ATTRIBUTE_FAMILY / config/asteria.php)。命令会回退到 variant_productdefault

订单是游客单: 先跑用户迁移,并确认 Magento customer_id / 邮箱能对上 migrated_from_asteria_id 或 Bagisto 邮箱。

旧密码登不上: 新迁用户密码在 legacy_password。Web 登录与 API 登录都会走 Magento 1 MD5(可带 salt)校验,成功后改成 bcrypt。已存在的 Bagisto 账号被「关联」时不会写入 legacy_password,仍用原 Bagisto 密码。

重复跑会不会翻倍: 不会。用户按 Asteria ID / 邮箱,地址按 asteria_address_id,商品按 SKU 或 migrated_from_asteria_id(再跑会更新内容),订单/评论按 migrated_from_asteria_id