SQL:
SELECT p.project_id, p.name,
COALESCE(NULLIF(json_agg(a.*)::TEXT, '[null]'), '[]')::JSON AS apps
FROM project p LEFT JOIN app a USING (project_id)
WHERE p.user_id=19
GROUP BY p.project_id, p.name ORDER BY project_id
结果:
"戈兰"
type Project struct {
ID int64 `db:"project_id, primarykey, autoincrement" json:"id"`
UserID int64 `db:"user_id" json:"user_id"`
Name string `db:"name" json:"name"`
Status int `db:"status" json:"status"`
UpdatedAt int64 `db:"updated_at" json:"updated_at"`
CreatedAt int64 `db:"created_at" json:"created_at"`
Apps json.RawMessage `json:"apps"`
}
func GetProjects(userID int64, page string) []Project {
var projects []Project
var err error
_, err = db.GetDB().Select(&projects, "SELECT p.project_id, p.name, COALESCE(NULLIF(json_agg(a.*)::TEXT, '[null]'), '[]')::JSON AS apps FROM project p LEFT JOIN app a USING (project_id) WHERE p.user_id=$1 GROUP BY p.project_id, p.name ORDER BY project_id LIMIT 10 OFFSET $2", userID, page)
fmt.Println("err", err)
return projects
}
并使用以下语句返回结果:c.JSON(200, gin.H{"data": projects})
如果只有一个项目,它就可以工作
但如果有多个项目,则会出现以下错误:
错误:json: error calling MarshalJSON for type json.RawMessage: invalid character '"' after top-level value
有什么建议吗?
附言:我是Golang的新手
3条答案
按热度按时间klr1opcd1#
你可以使用这个站点http://json2struct.mervine.net/来根据结果得到正确的结构体。只需要复制选择的结果,然后生成你想要的结构体。
或者您可以生成具有Project结构数组新类型:
szqfcxe22#
我使用下面的answer解决方案使其工作
我不知道这个解决方案有多简洁,但我最终创建了我自己的数据类型
JSONRaw
。DB驱动程序将其视为[]btye
,但在Go代码中仍可以将其视为json.RawMessage
。这是从encoding/json库复制粘贴
MarshalJSON
和UnmarshalJSON
的重新实现。但我想知道除了这个,是否还有其他干净的方法?
希望这也对其他人有所帮助。
guykilcj3#
我使用了以下链接https://www.alexedwards.net/blog/using-postgresql-jsonb
和http://json2struct.mervine.net/之间的关系
让它工作。我挣扎了很长时间,然后意识到结构做到了这一点。