【发布时间】:2020-10-31 06:30:30
【问题描述】:
我有一个product-image (1:M) 关系,基本上我想将这些图像映射到我的结构中的一个切片。我正在使用 sqlx 库使它更容易一些。
我搜索了一段时间,也许最好的答案在这个帖子中:Efficiently mapping one-to-many many-to-many database to struct in Golang。 创建视图并以 json 格式返回所有内容的答案是可行的,但感觉有点 hacky。
理想情况下,我想做的是使用 postgres json_agg 在 images 列中返回与我的类型匹配的 json 数组,以便我可以扫描到它。
我用 nodejs 做了几次,但我不知道怎么做。我需要实现自定义Scan 和Value 方法还是有更简单的方法。我没有展示这个,但我也有一个 1:1 的类别,我可以将该类别嵌入到产品中并进行左连接,它适用于 sqlx,但不适用于图像类型。
简化模型
type Image struct {
ID int,
URL string,
ProductID int
}
type ImageList []*Image
type Product struct {
ID int `db:"id"`
Name string `db:"name"`
Images ImageList `db:"images"`
}
数据库表
create table product (
id int generated always as identity primary key,
name varchar(255),
);
create table product_image (
id int generated always as identity primary key,
url text not null,
product_id int references product(id)
);
我现在正在尝试这样的事情:
q := `SELECT
p.*,
COALESCE(JSON_AGG(img.*) FILTER (WHERE img.product_id IS NOT NULL), '[]'::json) AS images
FROM product p
LEFT JOIN product_image img ON p.id = img.product_id
WHERE p.id = 1
GROUP BY p.id`
var p Product
if err := sqlxdb.Get(&p, q); err != nil {
fmt.Printf("Error: %v\n", err)
}
我收到此错误:
sql: Scan error on column index 26, name "images": unsupported Scan, storing driver.Value type []uint8 into type *model.ImageList
这似乎是一个超级常见的场景,但我找不到任何例子...... 或者最后我这样做是不是很愚蠢,因为我可以在 JS 中执行 forEach 并执行 50 个查询来获取每个产品的所有图像。
【问题讨论】:
-
只是好奇,如果
product_image行与ON p.id = img.product_id连接,过滤器where 子句WHERE img.product_id IS NOT NULL是否会导致false?不是没有必要吗? -
您可以为
*ImageList实现sql.Scanner接口,让实现类型断言interface{}参数到[]byte,然后将其结果与接收者一起传递给json.Unmarshal。即play.golang.org/p/Zh50aAB3YA1 -
@mkopriva 我试过了,但实际上我得到了同样的错误,很有趣。无论如何感谢您的帮助。对于查询,如果我不编写过滤器,它实际上给了我这样的数组,里面有 null。 [空值]。我想还有其他方法可以做到这一点,但这个查询有效。
标签: postgresql go struct sqlx