Skip to content

订单重构3期

主要内容

  1. 迁移MongoDB 的订单数据到 MySQL
  2. 修改station、manage、order剩余直接用到MongoDB操作的代码

步骤

  1. 上一个版本:修改station,manage关于订单修改的脚本和order服务的代码,改成双写,MySQL有数据的先写mysql,再写mongo,mysql没有数据的,先把要修改后的数据创建到mysql,再写mongo
  2. 编写脚本,把历史数据同步到mysql,检查两边数据,保证两边数据一致
  3. 再上一个版本,把查mongo的操作改成mysql,检查mysql设计的表字段是否完整
  4. 最后过一段时间,上一个版本,删掉双写的代码

表设计

tbl_order

    CREATE TABLE IF NOT EXISTS `tbl_order_{}` (
        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `order_id` varchar(32) NOT NULL COMMENT '订单ID',
        `out_order_id` int(11) NOT NULL DEFAULT '0' COMMENT '第三方order_id',
        `type` tinyint(4) NOT NULL COMMENT '订单类型(1:PL,2:LK)',

        `status` tinyint(4) NOT NULL default '1' COMMENT '状态',
        `pay_status` tinyint(4) NOT NULL default '1' COMMENT '支付状态',
        `settle_way` tinyint(4) NOT NULL default '1' COMMENT '商户结算方式',
        `freeze` tinyint(4) NOT NULL default '0' COMMENT '订单锁定状态',
        `pstatus` tinyint(4) NOT NULL DEFAULT '0',

        `customer_pay_method` tinyint(4) NOT NULL default '1' COMMENT '付款方式',

        `group_id` int(11) NOT NULL COMMENT 'group_id',
        `station_id` varchar(12) NOT NULL COMMENT '站点ID',
        `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户ID或站点ID,tbl_user.id',
        `shop_id` varchar(12) NOT NULL COMMENT '店铺ID或站点ID,tbl_address.id',

        `shop_address` varchar(256) NOT NULL DEFAULT '' COMMENT '店铺收货地址',
        `shop_name` varchar(128) NOT NULL DEFAULT '' COMMENT '店铺名',
        `receiver_name` varchar(50) NOT NULL DEFAULT '' COMMENT '收货人',
        `receiver_phone` varchar(50) NOT NULL DEFAULT '' COMMENT '收货人电话',
        `receive_begin_time` datetime NOT NULL COMMENT '收货开始时间',
        `receive_end_time` datetime NOT NULL COMMENT '收货结束时间',
        `area_id` int(11) NOT NULL COMMENT '区域ID,tbl_area.id,原mongo的address_sign_id',
        `district_code` varchar(12) NOT NULL DEFAULT '' COMMENT '城市码,tbl_user.district_code',
        `time_config_id` varchar(12) NOT NULL DEFAULT '' COMMENT '时间配置ID,service_time.id',

        `order_price` decimal(15,4) NOT NULL COMMENT '下单金额',
        `origin_order_price` decimal(15,4) NOT NULL COMMENT '原下单金额',
        `fake_order_price` decimal(15,4) NOT NULL COMMENT '伪原价:每件商品 max(原价下单金额, 规则价下单金额) 之和',

        `outstock_price` decimal(15,4) NOT NULL COMMENT '出库金额',
        `freight_price` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT '运费',
        `refund_price` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT '退货金额',
        `abnormal_price` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT '异常金额',
        `account_price` decimal(15,4) NOT NULL COMMENT '应付金额(包含运费、异常、退货)',

        `paid_amount` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT '已支付金额',
        `refund_amount` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT '退款金额',
        `actual_amount` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT '实付金额',

        `order_time` datetime NOT NULL COMMENT '下单时间',
        `sorting_time` datetime DEFAULT NULL COMMENT '分拣时间',
        `receive_time` datetime DEFAULT NULL COMMENT '收货时间,用户收到的真实时间,以前没有',
        `distribute_time` datetime DEFAULT NULL COMMENT '配送时间',
        `pay_time` datetime DEFAULT NULL COMMENT '支付时间',
        `expire_time` datetime DEFAULT NULL COMMENT '过期时间',
        `close_time` datetime DEFAULT NULL COMMENT '真正关闭时间',
        `latest_pay_time` datetime DEFAULT NULL COMMENT '最后支付时间',

        `refund_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0 不是整单退款,1 整单退款',
        `remark` varchar(128) NOT NULL DEFAULT '' COMMENT '订单备注',
        `batch_remark` varchar(128) NOT NULL DEFAULT '' COMMENT '分拣备注',
        `pay_remark` varchar(128) NOT NULL DEFAULT '' COMMENT '付款备注',
        `aggregate_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '聚合方式,原mongo的is_aggregation',
        `client` tinyint(4) NOT NULL DEFAULT '0' COMMENT '下单渠道',
        `print_times` int(11) NOT NULL DEFAULT '0' COMMENT '打印数',
        `is_purchase_task_new_synced` tinyint(4) NOT NULL DEFAULT '0' COMMENT '同步采购标识',

        `create_time` datetime NOT NULL COMMENT '创建时间',
        `modify_time` datetime NOT NULL COMMENT '最后修改时间',
        `delete_time` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '删除时间,未删除为 1-1-1 00:00:00',
        `extra1` int(11) NOT NULL DEFAULT '0',
        `extra2` int(11) NOT NULL DEFAULT '0',
        `extra3` int(11) NOT NULL DEFAULT '0',
        `extra4` varchar(128) NOT NULL DEFAULT '',
        `extra5` varchar(128) NOT NULL DEFAULT '',
        `extra6` varchar(128) NOT NULL DEFAULT '',
        `extra7` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
        `extra8` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
        `extra9` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
        `extra10` decimal(15,4) NOT NULL DEFAULT '0.0000',
        PRIMARY KEY (`id`),
        KEY `order_id` (`order_id`),
        KEY `shop_id_order_time_station_id` (`shop_id`, `order_time`, `station_id`),
        KEY `user_id_order_time` (`user_id`, `order_time`),
        KEY `receive_begin_time_time_config_id` (`receive_begin_time`, `time_config_id`),
        KEY `receive_begin_time_order_time_station_id` (`receive_begin_time`, `order_time`, `station_id`),
        KEY `receive_begin_time_station_id_time_config_id` (`receive_begin_time`, `station_id`, `time_config_id`),
        KEY `order_time_station_id_time_config_id` (`order_time`, `station_id`, `time_config_id`),
        KEY `order_time_district_code` (`order_time`, `district_code`)
    ) ENGINE=InnoDB;

不是必有字段(统计可能不全,代码编写还是要每个字段兼容):
fake_total_price
salemenu_ids
origin_total_price
distribute_time
paid_amount
expire_time
modify_time
refund_amount
pay_status
settle_way
create_time
real_pay
close_time
freeze
batch_remark
pay_remark



字段转换:
order_relation = {
    '_id': 'id',
    'order_id': 'order_id',
    'out_order_id': 'out_order_id',
    'type': 'type',
    'status': 'status',
    'pay_status': 'pay_status',
    'settle_way': 'settle_way',
    'freeze': 'freeze',
    'pstatus': 'pstatus',
    'customer.extender.pay_method': 'customer_pay_method',
    'station_id': 'station_id',
    'customer.uid': 'user_id',
    'customer.address_id': 'shop_id',
    'customer.extender.resname': 'shop_address',
    'customer.address': 'shop_name',
    'customer.receiver_name': 'receiver_name',
    'customer.receiver_phone': 'receiver_phone',
    'customer.receive_begin_time': 'receive_begin_time',
    'customer.receive_end_time': 'receive_end_time',
    'customer.address_sign_id': 'area_id',
    'district_code': 'district_code',
    'time_config_id': 'time_config_id',
    'total_price': 'order_price',
    'origin_total_price': 'origin_order_price',
    'fake_total_price': 'fake_order_price',
    'real_price': 'outstock_price',
    'freight': 'freight_price',
    'refund_money': 'refund_price',
    'abnormal_money': 'abnormal_price',
    'total_pay': 'account_price',
    'paid_amount': 'paid_amount',
    'refund_amount': 'refund_amount',
    'real_pay': 'actual_amount',
    'date_time': 'order_time',
    'sorting_time': 'sorting_time',
    'receive_time': 'receive_time',
    'distribute_time': 'distribute_time',
    'pay_time': 'pay_time',
    'expire_time': 'expire_time',
    'close_time': 'close_time',
    'latest_pay_time': 'latest_pay_time',
    'remark': 'remark',
    'batch_remark': 'batch_remark',
    'pay_remark': 'pay_remark',
    'is_aggregation': 'aggregate_type',
    'print_times': 'print_times',
    'is_purchase_task_new_synced': 'purchase_task_sync_uuid',
    'create_time': 'create_time',
    'modify_time': 'modify_time',
    'delivery_time': receive_time
}

purchase_task_sync_uuid
is_purchase_task_new_synced

is_purchase_task_new_synced->purchase_task_sync_uuid

废除字段(记得查询的时候,要把这些迁移到其他表里的字段查出来):
_abnormal_lock
salemenu_ids    销售单ids,tbl_order_detail里有salemenu_id
purchase_task_sync_uuid
token
order_type
refunds       放到tbl_order_detail里
abnormals     放到tbl_order_detail里
coupon_max_discount_percent         tbl_coupon
coupon_amount                                       tbl_coupon
coupon_id                                               tbl_coupon
coupon_min_total_price                  tbl_coupon

tbl_order_serial

CREATE TABLE `tbl_order_serial` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `order_id` varchar(32) NOT NULL COMMENT '订单ID',
    `serial` varchar(64) NOT NULL DEFAULT '' COMMENT '订单修改序列号',
    `pstatus` tinyint(4) NOT NULL DEFAULT '0',
    `create_time` datetime NOT NULL COMMENT '创建时间',
    `modify_time` datetime NOT NULL COMMENT '最后修改时间',
    `delete_time` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '删除时间,未删除为 1-1-1 00:00:00',
    `extra1` int(11) NOT NULL DEFAULT '0',
    `extra2` varchar(128) NOT NULL DEFAULT '',
    PRIMARY KEY (`id`),
    KEY `order_id` (`order_id`),
) ENGINE=InnoDB;

tbl_order_detail

CREATE TABLE `tbl_order_detail` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `order_id` varchar(32) NOT NULL COMMENT '订单ID',
    `sku_id` varchar(20) NOT NULL COMMENT '商品ID',
    `sku_version` int(11) NOT NULL COMMENT 'sku版本号',
    `sku_name` varchar(50) NOT NULL DEFAULT '' COMMENT 'sku名称',
    `sku_sale_unit_name` varchar(12) NOT NULL DEFAULT '' COMMENT 'sku销售单位',
    `sku_std_unit_name` varchar(12) NOT NULL DEFAULT '' COMMENT 'sku基本单位',
    `sku_std_sale_price` decimal(15,4) NOT NULL COMMENT 'sku售价(基本单位)',
    `sku_std_outstock_quantity` decimal(15,4) NOT NULL COMMENT 'sku基本单位出库数',
    `sku_std_accept_quantity` decimal(15,4) NOT NULL COMMENT 'sku基本单位结账数',
    `sku_attrition_rate` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT 'sku损耗率',
    `sku_sale_ratio` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT 'sku规格',
    `sku_is_weight` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否称重商品',
    `sku_is_price_timing` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否时价商品',
    `salemenu_id` varchar(12) NOT NULL COMMENT '销售单ID',

    `spu_id` varchar(20) NOT NULL COMMENT 'spu id',
    `spu_version` int(11) NOT NULL COMMENT 'spu版本号,新增',
    `spu_remark` varchar(50) NOT NULL DEFAULT '' COMMENT '商品备注',

    `sale_price` decimal(15,4) NOT NULL COMMENT '销售价',
    `origin_sale_price` decimal(15,4) COMMENT '原销售价',
    `order_price` decimal(15,4) NOT NULL COMMENT '下单金额',
    `origin_order_price` decimal(15,4) NOT NULL COMMENT '原下单金额',
    `fake_order_price` decimal(15,4) NOT NULL COMMENT '伪原价:每件商品 max(原价下单金额, 规则价下单金额) 之和',
    `outstock_price` decimal(15,4) NOT NULL COMMENT '出库金额',
    `account_price` decimal(15,4) NOT NULL COMMENT '应付金额(不包含异常退货)',

    `quantity` decimal(15,4) NOT NULL COMMENT '下单数(包含损耗)',
    `purchase_quantity` decimal(15,4) NOT NULL COMMENT '下单数',
    `outstock_quantity` decimal(15,4) NOT NULL COMMENT '出库数',
    `accept_quantity` decimal(15,4) NOT NULL COMMENT '结账数',
    `weighting_quantity` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT '称重数',

    `sorting_is_weighted` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否已称重',
    `sorting_out_of_stock` tinyint(4) NOT NULL DEFAULT '0' COMMENT '缺货标记',
    `sorting_way` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0: 未分拣, 1: mes, 2: pda',
    `price_rule_id` varchar(20) NOT NULL DEFAULT '0' COMMENT '锁价规格ID',
    `cost` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT '成本价格',
    `stock_count` decimal(15,4) NOT NULL DEFAULT '0.0000' COMMENT '缺货任务数',
    `search_text` text NOT NULL DEFAULT '' COMMENT '商品搜索',

        `sort_num` int NOT NULL DEFAULT '0' COMMENT '商品排序号',
    `pstatus` tinyint(4) NOT NULL DEFAULT '0',
    `create_time` datetime NOT NULL COMMENT '创建时间',
    `modify_time` datetime NOT NULL COMMENT '最后修改时间',
    `delete_time` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '删除时间,未删除为 1-1-1 00:00:00',
    `extra1` int(11) NOT NULL DEFAULT '0',
    `extra2` int(11) NOT NULL DEFAULT '0',
    `extra3` int(11) NOT NULL DEFAULT '0',
    `extra4` varchar(128) NOT NULL DEFAULT '',
    `extra5` varchar(128) NOT NULL DEFAULT '',
    `extra6` varchar(128) NOT NULL DEFAULT '',
    `extra7` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
    `extra8` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
    `extra9` datetime NOT NULL DEFAULT '0001-01-01 00:00:00',
    `extra10` decimal(15,4) NOT NULL DEFAULT '0.0000',
    PRIMARY KEY (`id`),
    KEY `order_id_sku_id` (`order_id`, `sku_id`),
    KEY `sku_id` (`sku_id`),
    # 未完待续
) ENGINE=InnoDB;


不是必有字段(统计可能不全,代码编写还是要每个字段兼容):
details.material.cost
details.material.stock_count
details.sync_origin
details.salemenu_id
details.real_is_weight
details.purchase_quantity
details.attrition_rate
details.is_price_timing
details.origin_item_price
details.origin_sale_price
details.is_weight
details.fake_item_price
details.rule_id
details.out_of_stock
details.sort_way

字段转换:
details.id  sku_id
details.version  sku_version
details.name    sku_name
details.sale_unit_name  sku_sale_unit_name
details.material.std_unit_name  sku_std_unit_name
details.material.std_sale_price sku_std_sale_price
details.material.real_std_count sku_std_outstock_quantity
details.material.accept_std_count   sku_std_accept_quantity
details.attrition_rate  sku_attrition_rate
details.material.sale_ratio sku_sale_ratio
details.real_is_weight  sku_is_weight
details.is_price_timing sku_is_price_timing
details.salemenu_id salemenu_id
details.material.spu_id spu_id
details.spu_remark  spu_remark
details.sale_price  sale_price
details.origin_sale_price   origin_sale_price
details.total_item_price    order_price
details.origin_item_price   origin_order_price
details.fake_item_price   fake_order_price    
details.real_item_price  outstock_price
details.total_item_pay  account_price
details.quantity    quantity
details.purchase_quantity   purchase_quantity
details.real_quantity   outstock_quantity
details.accept_quantity accept_quantity
details.weighting_quantity  weighting_quantity
details.is_weight   sorting_is_weighted
details.out_of_stock    sorting_out_of_stock
details.sort_way    sorting_way
details.rule_id price_rule_id
details.material.cost   cost
details.material.stock_count    stock_count
details.search_text search_text


废除字段:
sort_station_ids
sync_origin

tbl_order_supply_chain

CREATE TABLE `tbl_order_supply_chain` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `origin_order_id` varchar(32) NOT NULL ,
    `origin_sku_id` varchar(11) NOT NULL ,
    `origin_quantity` decimal(15,4) NOT NULL,
    `up_order_id` varchar(32) NOT NULL ,
    `up_sku_id` varchar(11) NOT NULL ,
    `up_quantity` decimal(15,4) NOT NULL,
    `up_station_id` varchar(10) NOT NULL COMMENT '站点ID',
    `aggregate_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '聚合方式',
    `time_config_id` varchar(10) NOT NULL DEFAULT '' COMMENT '时间配置ID',
    `pstatus` tinyint(4) NOT NULL DEFAULT '0',
    `create_time` datetime NOT NULL COMMENT '创建时间',
    `modify_time` datetime NOT NULL COMMENT '最后修改时间',
    `delete_time` datetime NOT NULL DEFAULT '0001-01-01 00:00:00' COMMENT '删除时间,未删除为 1-1-1 00:00:00',
    `extra1` int(11) NOT NULL DEFAULT '0',
    `extra2` int(11) NOT NULL DEFAULT '0',
    `extra3` int(11) NOT NULL DEFAULT '0',
    `extra4` varchar(128) NOT NULL DEFAULT '',
    `extra5` varchar(128) NOT NULL DEFAULT '',
    `extra6` varchar(128) NOT NULL DEFAULT '',
    PRIMARY KEY (`id`),
    KEY `origin_order_id_sku_id` (`origin_order_id`, `origin_sku_id`),
    KEY `up_order_id_sku_id` (`up_order_id`, `up_sku_id`)
) ENGINE=InnoDB;

代码修改

station

crontab脚本       涉及7个多脚本
tools/crontab_tasks/order_utils.py  
脚本:
tools/crontab_tasks/check_order2purchase_task.py
tools/crontab_tasks/order_count_everyday.py
tools/crontab_tasks/station_settlement.py
tools/crontab_tasks/sync_driver_collection.py
tools/crontab_tasks/update_order_num_fresh.py
tools/crontab_tasks/update_out_stock_sku.py
tools/crontab_tasks/update_sku_frequency.py

注意:记得添加OrderConn报错
regular脚本       涉及1个多脚本
tools/regular/clear_station_data.py 清除站点脚本

tmp脚本
忽略
订单加解锁           涉及2个接口
common/mongo/order_connection.py:15
接口
order/edit
order/edit_old

manage

crontab脚本
tools/order_utils.py    涉及2个脚本
脚本:
tools/order_details_statistics.py
tools/update_order_sales.py

order项目的订单的相关代码

更新代码添加双写逻辑

order/views/order_new.py:623  OrderBulkUpdateView
pay/service/pay_service.py:712      on_pay_success
pay/service/pay_service.py:471      pay_order
pay/service/pay_service.py:486      pay_order
pay/service/pay_service.py:952      strike_order
tools/release_order_stock.py:72     set_close_order
weight/views/order_weight.py:104    WeightOrderBulkUpdateView

其他剩余:
common/mongo/order.py 里的更新操作

查询代码转移到mysql

order/views/order_new.py:519        OrderListView
tools/release_order_stock.py:51     get_close_orders
pay/service/pay_service.py:892  strike_order

其他剩余:
common/mongo/order.py 里的更新操作

刷数据脚本

脚本1:能按照group_id,全部group_id,时间,从mongo刷到mysql

脚本2:校验最近一段时间 mongo和mysql数据的一致性,还要实时监控最新数据是否两边一致

规划

时间 任务 规划人员
4月3号-4月10号(5天) 完成station、ma、order对应的双写 儒端
4月11号-4月15号(3天) 测试、灰度客户 李铭
4月3号-4月15号(8天) 导数据到test机器
编写2个脚本
验证脚本,检查数据是否完整和一致
文峰
4月16号-4月19号(4天) 把station、ma、order对应的查询改到mysql
期间检查数据完整性的脚本一直运行
儒端
4月22号-月底 测试、灰度客户、上线 李铭
最后 抽个时间,上个版本,把双写的逻辑去掉 儒端