一直在做大量的搜索,虽然我可以找到一堆很好的文章来解释如何直接使用pq包。我无法在go-gorm和postgresql方言的上下文中工作。
如果在checks.go中使用ChecksMap,它不允许我插入,而是会让我找到。如果我使用postgres.jsonb,它允许我插入和查询,但是找到的记录将是jsonb的。
Gorm使用指针的结构来确定db表和模式。当使用泛型searchHandler实用程序从API返回json响应时,这会引起头痛。对于任何非jsonb类型,gorm使用正确的结构并使用json标记,但是对于jsonb,因为它没有引用jsonb的"struct“,所以它不能使用json标记。这将导致返回API json具有大写键。
{
results: {
id: "123",
someId: "456",
results: [
{
Description: "foobar"
}
]
}
}是否有一种优雅的方法来处理这类事情,以便jsonb结果列具有正确的结构并使用低限值的json标记?我只是想做一些不该在go-gorm的背景下做的事情吗?
POSTGRESQL
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 handlinggetChecks.go
var checks Checks
err := db.Find(&checks).Error
// ... some error handlingsearchHandler.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),
})
}
}发布于 2019-09-03 17:20:07
您可以使用自定义的ChecksMap类型,但在其值接收器上实现driver.Valuer接口,而不是指针接收者。
因此,与其:
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"`
}(虽然我还没有测试过这个,所以我不能百分之百地确定gorm将如何处理这个案件)
https://stackoverflow.com/questions/57774957
复制相似问题