You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django对接Amazon SP-API:数据持久化与模型设计咨询

Django + Amazon SP-API 仪表盘模型设计问题解答

背景说明

我正在用Amazon SP-API等外部API在Django里搭建简易仪表盘,目前会遍历100个带不同刷新令牌的账号拉取客户订单,推送到数据库,同时用定时任务(cronjob)调用Amazon API,通过Django的update_or_create实现数据的保存和更新。

当前使用的模型代码:

class VendorOrder(models.Model):
    id = models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')
    purchase_order_number = models.CharField(max_length = 30)
    purchase_order_state = models.CharField(max_length = 30, default = "", null = True, blank = True)
    purchase_order_date = models.DateTimeField()
    last_updated_date = models.DateTimeField(null = True, blank = True)
    window_start = models.DateTimeField()
    window_end = models.DateTimeField()
    selling_party = models.CharField(max_length = 100)   
    warehouse = models.CharField(max_length = 100)
    item_sequence_number = models.IntegerField(null = True, blank = True)
    buyer_product_identifier = models.CharField(max_length = 30, default ="", null = True, blank = True)
    vendor_product_identifier = models.CharField(max_length = 30, default ="", null = True, blank = True)
    ordered_quantity = models.DecimalField(max_digits=20, decimal_places=2, null = True, blank = True)
    accepted_quantity = models.DecimalField(max_digits=20, decimal_places=2, null = True, blank = True)
    received_quantity = models.DecimalField(max_digits=20, decimal_places=2, null = True, blank = True)
    net_cost = models.DecimalField(max_digits=20, decimal_places=2, null = True, blank = True)
    net_cost_currency = models.CharField(max_length = 10, default ="", null = True, blank = True)
    total_cost = models.DecimalField(max_digits=20, decimal_places=2, null = True, blank = True)

问题解答

1. 是否需要新建日期模型存储window_start和window_end?

不需要单独新建日期模型,理由如下:

  • window_start和window_end是采购订单级别的属性,每个purchase_order_number对应唯一的窗口日期,与订单本身强关联,拆分到单独模型会增加数据冗余和关联查询成本。
  • 可以先拉取订单基础数据存入数据库(将window_start和window_end设为null=True),再调用第二个接口获取窗口日期,通过purchase_order_number匹配后直接更新原模型的对应字段即可。

2. 订单条目是否需要单独建模型?用JSON Field还是拆分模型?

建议拆分出单独的订单条目模型,不推荐用JSON Field存储整个订单,具体分析如下:

为什么不推荐JSON Field?

  • 数据可操作性差:查询特定字段或更新单个属性时,需要解析整个JSON,无法利用数据库索引优化性能。
  • 数据无约束:数据库层面无法校验JSON内字段的类型和合法性,容易产生脏数据。
  • 动态更新繁琐:更新accepted_quantity这类字段时,需要先读取整个JSON修改再重新写入,不如直接更新数据库字段高效。

模型拆分方案

将订单拆分为订单头(存储订单级公共属性)和订单条目(存储单个商品的明细属性)两个模型:

class VendorOrderHeader(models.Model):
    # 订单级公共属性
    purchase_order_number = models.CharField(max_length=30, unique=True)
    purchase_order_state = models.CharField(max_length=30, default="", null=True, blank=True)
    purchase_order_date = models.DateTimeField()
    last_updated_date = models.DateTimeField(null=True, blank=True)
    window_start = models.DateTimeField(null=True, blank=True)
    window_end = models.DateTimeField(null=True, blank=True)
    selling_party = models.CharField(max_length=100)   
    warehouse = models.CharField(max_length=100)

class VendorOrderItem(models.Model):
    # 订单条目明细属性
    order_header = models.ForeignKey(VendorOrderHeader, on_delete=models.CASCADE, related_name='items')
    item_sequence_number = models.IntegerField()
    buyer_product_identifier = models.CharField(max_length=30, default="", null=True, blank=True)
    vendor_product_identifier = models.CharField(max_length=30, default="", null=True, blank=True)
    ordered_quantity = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True)
    accepted_quantity = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True)
    received_quantity = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True)
    net_cost = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True)
    net_cost_currency = models.CharField(max_length=10, default="", null=True, blank=True)
    total_cost = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True)

    class Meta:
        unique_together = ('order_header', 'item_sequence_number')  # 保证同一订单下的条目唯一

动态更新实现

定时任务调用API获取更新数据时:

  1. 通过purchase_order_number找到对应的VendorOrderHeader实例
  2. 以order_header + item_sequence_number为匹配条件,调用update_or_create方法,精准更新VendorOrderItem的目标字段(如accepted_quantity)
  3. 可给VendorOrderItem添加last_updated_date字段,每次更新时自动设置为当前时间,便于跟踪变更记录

内容的提问来源于stack exchange,提问作者Krapi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:25:24