反序列化嵌套的JSON,或者简单地在Go中向前传递

反序列化嵌套的JSON,或者简单地在Go中向前传递,json,postgresql,go,go-gorm,Json,Postgresql,Go,Go Gorm,使用Go构建一个基本API,我将JSON存储在postgres表的JSON字段中,以及一些其他(普通)数据类型。使用我的模型,我只是尝试从数据库中获取一行并将其作为JSON转发 使用将数据反序列化为结构,大多数映射都会无缝进行,JSON除外,JSON根据所选数据类型呈现为bytearray或字符串 以下是模型(已更新): 典型的JSON如下所示(从数据库中): 所以我的想法是,我只是想传递这些数据,而不是改变它,或者将其反序列化为Go结构或任何东西。控制员/路线如下: func GetItem(

使用Go构建一个基本API,我将JSON存储在postgres表的JSON字段中,以及一些其他(普通)数据类型。使用我的模型,我只是尝试从数据库中获取一行并将其作为JSON转发

使用将数据反序列化为结构,大多数映射都会无缝进行,JSON除外,JSON根据所选数据类型呈现为bytearray或字符串

以下是模型(已更新):

典型的JSON如下所示(从数据库中):

所以我的想法是,我只是想传递这些数据,而不是改变它,或者将其反序列化为Go结构或任何东西。控制员/路线如下:

func GetItem(c *gin.Context) {
    id, err := strconv.Atoi(c.Param("id"))

    // Convert Parameter to int, for db query
    if err != nil {
        panic(err)
    }

    // Get the DB context
    db, ok := c.MustGet("databaseConnection").(gorm.DB)
    if !ok {
        // Do something
    }

    // Hold the structified item here.
    var returnedItem models.Item

    // Get the db row
    db.Where(&models.Item{ItemID: id}).First(&returnedItem)

    if c.Bind(&returnedItem) == nil {

        // Respond with the struct as json
        c.JSON(http.StatusOK, returnedItem)
    }
}
其响应为以下JSON(stats为JSON.RawMessage):

或者(使用stats作为字符串):

到目前为止,我试图将JSON映射到一个结构(由于动态数据以及我选择JSON的原因,这变得很困难),我必须简单地传递什么选项呢

我意识到这里有一些神奇的地方,c.JSON自动(?)将所有数据从struct编组到JSON,但希望有某种方法避免编组JSON数据

使用ItemInfo子结构运行时,会出现以下错误:

2016/01/07 08:21:08 Panic recovery -> reflect.Set: value of type []uint8 is not assignable to type []models.ItemInfo
/usr/local/go/src/runtime/panic.go:423 (0x42a929)
        gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/usr/local/go/src/reflect/value.go:2158 (0x5492ce)
        Value.assignTo: panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
/usr/local/go/src/reflect/value.go:1327 (0x546195)

编辑:更新的代码:

创建一个子结构,如
itemInfo
或类似:

type itemInfo struct {
    Stat string `json:"stat"`
    Crit int    `json:"crit"`
}
然后在您的
项中
struct make

type Item struct {
    --snip--
    Context string `gorm:"column:context" json:"context"`
    Stats []itemInfo `gorm:"column:stats" json:"stats" sql:"json"`
    --snip--
}
然后,当你解组时,它应该正好进入项目信息


另外,我假设您使用的是暴雪API,我已经制作了一个包装器,您可以在这里查看它:要查看我是如何完成的,但它完全没有完成,我只实现了我在处理某些东西时需要的部分。

结果表明,在Item结构中提供一个附加属性,让GORM解组为[]字节,然后将字节数组解组为子结构:

// Item is a thing..
type Item 
    Stats           []byte    `gorm:"column:stats"  json:"stats"`
    StatsList       []ItemInfo `json:"iteminfo"`
}
然后像这样解开它:

err = json.Unmarshal(returnedItem.Stats, &returnedItem.StatsList)

感谢@evanmcdonnal的建议。

稍后可能会提供一个完整的答案,但我的建议相当简单,在您的类型中添加一个额外的字段,将json表示为
[]字节
,让GORM将其解组。之后,使用
encoding/json
[]字节
解组到目标结构中。我感觉很糟糕,因为我错过了你的评论,结果证明这是一个非常简单的解决方案。谢谢!谢谢你的回答。我已经设置了一个子结构,就像您的示例一样,不幸的是,在使用ORM获取行时会导致恐慌,消息如下:
2016/01/06 17:20:35恐慌恢复->反射。set:type[]uint8的值不能分配给type[]models。ItemInfo
我尝试在model.ItemInfo中使用数据类型,在int/字符串之间切换,没有真正的运气。@PerFröjd你能把你的代码放到你的问题中让我看一下吗?用新的结构和异常更新了问题
type itemInfo struct {
    Stat string `json:"stat"`
    Crit int    `json:"crit"`
}
type Item struct {
    --snip--
    Context string `gorm:"column:context" json:"context"`
    Stats []itemInfo `gorm:"column:stats" json:"stats" sql:"json"`
    --snip--
}
// Item is a thing..
type Item 
    Stats           []byte    `gorm:"column:stats"  json:"stats"`
    StatsList       []ItemInfo `json:"iteminfo"`
}
err = json.Unmarshal(returnedItem.Stats, &returnedItem.StatsList)