首页 > 解决方案 > 使用 GORM 解析 json 时重用 struct

问题描述

我正在尝试用 golang 编写我的第一个应用程序,我有一个 json 结构,我正在尝试使用 golang GORM 解析并存储到 DB。在 json 结构中,我有多个类似的价格结构,如下所示。我正在尝试为各种价格集创建一个通用结构,并为在 json 中任何位置出现的所有类型的价格集重用相同的价格集结构(还有其他几种具有相同结构的价格集类型)。

示例源 json -

"price_set": {
    "shop_money": {
        "amount": "5.00",
        "currency_code": "USD"
    },
    "presentment_money": {
        "amount": "5.00",
        "currency_code": "USD"
    }
},
"total_discount_set": {
    "shop_money": {
        "amount": "0.00",
        "currency_code": "USD"
    },
    "presentment_money": {
        "amount": "0.00",
        "currency_code": "USD"
    }
}

这就是我试图用我的 GO 代码做的事情。但是我遇到了外键问题,我不确定这是解决这个问题的最佳方法。

type Order struct {
    ID                     int64      `json:"id,omitempty"`
    OrderStatusURL         string     `json:"order_status_url,omitempty"`
    PresentmentCurrency    string     `json:"presentment_currency,omitempty"`
    TotalLineItemsPriceSet PriceSet   `json:"total_line_items_price_set,omitempty"`
    TotalDiscountSet       PriceSet   `json:"total_discounts_set,omitempty"`
    TotalShippingPriceSet  PriceSet   `json:"total_shipping_price_set,omitempty"`
    SubTotalPriceSet       PriceSet   `json:"subtotal_price_set,omitempty"`
    TotalPriceSet          PriceSet   `json:"total_price_set,omitempty"`
    TotalTaxSet            PriceSet   `json:"total_tax_set,omitempty"`
}

type PriceSet struct {
    ShopMoney        CurrencyHolder `json:"shop_money,omitempty"`
    PresentmentMoney CurrencyHolder `json:"presentment_money,omitempty"`
}

type CurrencyHolder struct {
    Amount       string `json:"amount,omitempty"`
    CurrencyCode string `json:"currency_code,omitempty"`
}

这个实现给了我错误

[错误] struct github.com/proj/proj-api/models.PriceSet 的字段 ShopMoney 的字段无效,需要为关系定义有效的外键或需要实现 Valuer/Scanner 接口

编辑——添加调用代码——

func CreateOrderTables(db *gorm.DB) {
    db.AutoMigrate(&models.Order{})
}

从调用

func CreateOrderTables(c *gin.Context) {
    DB := helper.OpenDBService()
    helper.CreateOrderTables(DB)
    close(DB, c, "Order tables created")
}

标签: goormgo-gorm

解决方案


您看到的错误是因为您在 Order 实体中包含了一组结构,但您没有告诉 GORM 与这些结构的关系是什么。一般来说,gorm 将实体结构内的结构视为相关实体(表)。

您布置 JSON 结构的方式是模棱两可的,如何最好地映射到简单的关系设计。我能想到的最简单的方法是使用 将所有这些字段放在同一个大表中gorm:"embedded",这会将这些结构字段放在同一个表中:

type Order struct {
    ID                     int64    `json:"id,omitempty"`
    OrderStatusURL         string   `json:"order_status_url,omitempty"`
    PresentmentCurrency    string   `json:"presentment_currency,omitempty"`
    TotalLineItemsPriceSet PriceSet `json:"total_line_items_price_set,omitempty" gorm:"embedded;embeddedPrefix:total_line_items_"`
    TotalDiscountSet       PriceSet `json:"total_discounts_set,omitempty"  gorm:"embedded;embeddedPrefix:total_discount_"`
    TotalShippingPriceSet  PriceSet `json:"total_shipping_price_set,omitempty"  gorm:"embedded;embeddedPrefix:total_shipping_"`
    SubTotalPriceSet       PriceSet `json:"subtotal_price_set,omitempty"  gorm:"embedded;embeddedPrefix:subtotal_"`
    TotalPriceSet          PriceSet `json:"total_price_set,omitempty"  gorm:"embedded;embeddedPrefix:total_"`
    TotalTaxSet            PriceSet `json:"total_tax_set,omitempty"  gorm:"embedded;embeddedPrefix:total_tax_"`
}

type PriceSet struct {
    ShopMoney        CurrencyHolder `json:"shop_money,omitempty" gorm:"embedded;embeddedPrefix:shop_"`
    PresentmentMoney CurrencyHolder `json:"presentment_money,omitempty" gorm:"embedded;embeddedPrefix:presentment_"`
}

type CurrencyHolder struct {
    Amount       string `json:"amount,omitempty"`
    CurrencyCode string `json:"currency_code,omitempty"`
}

这可行,尽管它不是一个很好的(阅读:规范化)设计。您可能需要考虑数据的关系结构以及如何最好地将其表示为数据库中的表,而不是首先设计 JSON :)


推荐阅读