0

Go を使用して基本的な API を構築し、postgres テーブルの JSON フィールドに JSON を他の (プレーンな) データ型と共に格納しました。私のモデルを使用して、単純にデータベースから行をフェッチし、それを JSON として転送しようとしています。

GORMを使用してデータを構造体に逆シリアル化すると、選択したデータ型に応じてバイト配列または文字列としてレンダリングされる JSON を除いて、ほとんどのマッピングがシームレスに行われます。

モデルは次のとおりです(更新済み):

type Item struct {
    --snip--
    Stats []ItemInfo `gorm:"column:stats" json:"stats" sql:"json"`
    --snip--
}

type ItemInfo struct {
    Stat        string      `json:"stat"`
    Amount      int         `json:"amount"`
}

典型的な JSON は次のようになります (DB から):

[{"stat": "Multistrike", "amount": 193}, {"stat": "Crit", "amount": 145}, 
 {"stat": "Agility", "amount": 254}, {"stat": "Stamina", "amount": 381}]

したがって、このデータを変更したり、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 で応答します (統計は json.RawMessage として):

{

    "context": "raid-finder",
    "stats": "W3sic3RhdCI6ICJWZXJzYXRpbGl0eSIsICJhbW91bnQiOiA0NX0sIHsic3RhdCI6ICJDcml0IiwgImFtb3VudCI6IDEwMH0sIHsic3RhdCI6ICJBZ2lsaXR5IiwgImFtb3VudCI6IDEwOX0sIHsic3RhdCI6ICJTdGFtaW5hIiwgImFtb3VudCI6IDE2M31d",
}

または、代わりに (統計を文字列として):

{
    "context": "raid-finder",
    "stats": "[{\"stat\": \"Versatility\", \"amount\": 45}, {\"stat\": \"Crit\", \"amount\": 100}, {\"stat\": \"Agility\", \"amount\": 109}, {\"stat\": \"Stamina\", \"amount\": 163}]",
}

これを単純に渡すために必要なオプションは何ですか?これまでのところ、JSON を構造体にマップしようとして失敗しました (動的データと、最初に JSON を選択した理由により、これは困難になります)。

c.JSONが構造体から JSON にすべてのデータを自動的にマーシャリングすることで、 gin-gonicからいくつかの魔法が起こっていることに気付きましたが、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)

編集:更新されたコード:

4

2 に答える 2

0

GORM の Item 構造体に追加のプロパティを提供して []byte にアンマーシャリングし、バイト配列をサブ構造体としてアンマーシャリングするのが最も簡単であることがわかりました。

// 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に感謝します。

于 2016-01-07T22:43:12.570 に答える