使用Gorm查询数据库并在HTTP响应中返回JSON的Golang代码。

huangapple go评论190阅读模式
英文:

golang querying database using Gorm and returning json in http response

问题

我是你的中文翻译助手,以下是你提供的代码的翻译:

我刚开始学习Go语言,并且正在使用Gorm来查询我的PostgreSQL数据库,但是在以字典格式返回数据时遇到了问题,其中宝可梦的类型作为键,对应一个包含该类型所有宝可梦的数组。

> json: 无法将对象解组为类型为[]models.Pokemon的Go值

以下是我的代码:

  1. type Pokemon struct {
  2. Name string `db:"name"`
  3. Type string `db:"type"`
  4. }
  5. pokemonTypes := [6]string{
  6. "fire",
  7. "electric",
  8. "water",
  9. "grass",
  10. }
  11. var retData struct {
  12. Poke []Pokemon
  13. }
  14. m := make(map[string][]Pokemon)
  15. for _, t := range pokemonTypes {
  16. pokemon := DB.Where(&Pokemon{Type: t}).Find(&retData.Poke)
  17. p, _ := json.Marshal(pokemon)
  18. err = json.Unmarshal(p, &retData.Poke) // 在这里出错
  19. if err != nil {
  20. fmt.Println(err)
  21. }
  22. m[category] = retData.Poke
  23. }
  24. data, _ := json.Marshal(m)
  25. w.Write(data) // HTTP响应

我在数据库中有以下数据:

  1. name | type
  2. ----------------------
  3. pikachu | electric
  4. charmander | fire
  5. blaziken | fire
  6. venusaur | grass
  7. treeko | grass
  8. squirtle | water

我希望以以下JSON格式返回数据:

  1. {
  2. "electric": [
  3. {"name": "pikachu", "type": "electric"},
  4. ],
  5. "fire": [
  6. {"name": "charmander", "type": "fire"},
  7. {"name": "blaziken", "type": "fire"}
  8. ],
  9. "grass": [
  10. {"name": "venusaur", "type": "grass"},
  11. {"name": "treeko", "type": "grass"},
  12. ],
  13. "water": [
  14. {"name": "squirtle", "type": "water"},
  15. ]
  16. }
英文:

I'm new to Go and am using Gorm to query my postgres database but am having trouble returning my data in a dictionary format, where the pokemon's type serves as a key to an array of all the pokemon of that type

> json: cannot unmarshal object into Go value of type []models.Pokemon

here's my code:

  1. type Pokemon struct {
  2. Name string `db:"name"`
  3. Type string `db:"type"`
  4. }
  5. pokemonTypes := [6]string{
  6. "fire",
  7. "electric",
  8. "water",
  9. "grass",
  10. }
  11. var retData struct {
  12. Poke []Pokemon
  13. }
  14. m := make(map[string][]Pokemon)
  15. for _, t := range pokemonTypes {
  16. pokemon := DB.Where(&Pokemon{Type: t}).Find(&retData.Poke)
  17. p, _ := json.Marshal(pokemon)
  18. err = json.Unmarshal(p, &retData.Poke) // getting error here
  19. if err != nil {
  20. fmt.Println(err)
  21. }
  22. m[category] = retData.Poke
  23. }
  24. data, _ := json.Marshal(m)
  25. w.Write(data) // http repsonse

I have this in my database

  1. name | type
  2. ----------------------
  3. pikachu | electric
  4. charmander | fire
  5. blaziken | fire
  6. venusaur | grass
  7. treeko | grass
  8. squirtle | water

I want to return data in this json format

  1. {
  2. electric”: [
  3. {"name": "pikachu", "type": "electric"},
  4. ],
  5. "fire": [
  6. {"name": "charmander", "type": "fire"},
  7. {"name": "blaziken", "type": "fire"}
  8. ],
  9. "grass": [
  10. {"name": "venusaur", "type": "grass"},
  11. {"name": "treeko", "type": "grass"},
  12. ],
  13. "water": [
  14. {"name": "squirtle", "type": "water"},
  15. ]
  16. }

答案1

得分: 2

DB.Where(&Pokemon{Type: t}).Find(&retData.Poke) 实际上返回了 *db 指针,你可以使用它来链式调用其他方法。
当你执行 .Find(&retData.Poke) 时,已经将 postgre 行反序列化到了你的结构体切片中。因此,pokemon 实际上不是你想象中的那样。

现在只剩下将 .Find().Error() 链接起来,以便返回并检查查询中的任何错误。就像这样:

  1. for _, t := range pokemonTypes {
  2. err := DB.Where(&Pokemon{Type: t}).Find(&retData.Poke).Error()
  3. if err != nil {
  4. fmt.Println(err)
  5. return
  6. }
  7. p, _ := json.Marshal(retData.Poke)
  8. err = json.Unmarshal(p, &retData.Poke)
  9. if err != nil {
  10. fmt.Println(err)
  11. return
  12. }
  13. m[category] = retData.Poke
  14. }

希望对你有所帮助!

英文:

DB.Where(&Pokemon{Type: t}).Find(&retData.Poke) esentially returns back the *db pointer which you can use to chain further methods.
You're already deserializing postgre rows into your struct slice when you do .Find(&retData.Poke). Thus, pokemon isn't actually what you think it is.

The only thing left now is to chain .Find() with a .Error() so that you can return and check any error in your query. Just like this :

  1. for _, t := range pokemonTypes {
  2. err := DB.Where(&Pokemon{Type: t}).Find(&retData.Poke).Error()
  3. if err != nil {
  4. fmt.Println(err)
  5. return
  6. }
  7. p, _ := json.Marshal(retData.Poke)
  8. err = json.Unmarshal(p, &retData.Poke)
  9. if err != nil {
  10. fmt.Println(err)
  11. return
  12. }
  13. m[category] = retData.Poke
  14. }

Hope it helps!

huangapple
  • 本文由 发表于 2017年8月27日 05:53:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/45899964.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定