gpt4 book ai didi

postgresql - go-gorm postgres 方言 : managing structs for jsonb insert and find to properly use json tags

转载 作者:行者123 更新时间:2023-11-29 13:08:41 25 4
gpt4 key购买 nike

我做了很多搜索,虽然我可以找到一堆解释如何直接使用 pq 包的好文章。我在 go-gorm 和 postgresql 方言的上下文中不知所措。

如果在 checks.go 中我使用 ChecksMap 它不让我插入但会让我找到。如果我使用 postgres.jsonb 它允许我插入和查询,但找到的记录将是 jsonb。

Gorm 使用指针的结构来确定数据库表和模式。当使用从 API 返回 json 响应的通用 searchHandler 实用程序时,这会引起头痛。对于任何非 jsonb 类型,gorm 使用适当的结构并使用 json 标签,但对于 jsonb,因为它没有对 jsonb 的“结构”的引用,所以它不能使用 json 标签。这会导致返回的 API json 具有大写键。

{
results: {
id: "123",
someId: "456",
results: [
{
Description: "foobar"
}
]
}
}

是否有一种优雅的方式来处理这类事情,以便 jsonb 结果列具有正确的结构并使用小写的 json 标签?我只是想做一些在 go-gorm 的上下文中不应该做的事情吗?

POSTGRESQL DDL

CREATE TABLE checks (
id text,
some_id text,
results jsonb
);

checks.go

type CheckRules struct {
Description string `json:"description"`
}

type ChecksMap map[string]CheckRules

type Checks struct {
ID string `gorm: "primary_key", json:"id"`
SomeID *string `json:"someId"`
Results postgres.jsonb `json:"results"` // <-- this
// results ChecksMap `gorm:"type:jsonb" json:"results"` // <-- or this
}

// func (cm *ChecksMap) Value() (driver.Value, error) {...}
// func (cm *ChecksMap) Scan(val interface{}) error {...}

insertChecks.go

var resultsVal = getResultsValue() // simplified
resJson, _ := json.Marshal(resultsVal)

checks := Checks{
SomeID: "123",
Results: postgres.Jsonb{ RawMessage: json.RawMessage(resJson) }
}

err := db.Create(&checks).Error
// ... some error handling

getChecks.go

var checks Checks

err := db.Find(&checks).Error
// ... some error handling

searchHandler.go

func SearchHandler(db *gorm.DB, model, results interface{}) func(c echo.Context) error {
return func(c echo.Context) error {
err := db.Find(results).Error
// ... some error handling

jsnRes, _ := json.Marshal(results) // <-- uppercase "keys"

return c.JSON(http.StatusOK, struct {
Results interface{} `json:"results"`
}{
Results: string(jsnRes),
})
}
}

最佳答案

您可以使用自定义 ChecksMap 类型,但在其值接收器(而不是指针接收器)上实现driver.Valuer 接口(interface)。

所以,而不是:

func (cm *ChecksMap) Value() (driver.Value, error) { ...

你会这样写:

func (cm ChecksMap) Value() (driver.Value, error) {
if cm == nil {
return nil, nil
}
return json.Marshal(cm)
}

或者,您可以使它与指针实现一起使用,但是您必须将字段转换为指针,例如:

type Checks struct {
ID string `gorm: "primary_key", json:"id"`
SomeID *string `json:"someId"`
Results *ChecksMap `json:"results"`
}

(虽然我还没有测试过,所以我不能 100% 确定 gorm 将如何处理这种情况)

关于postgresql - go-gorm postgres 方言 : managing structs for jsonb insert and find to properly use json tags,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57774957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com