You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PostgreSQL中用GORM Raw查询数组?遇类型不支持错误

解决GORM Raw SQL映射json_agg到[]string报错的问题

问题原因

json_agg(k.name)返回的是PostgreSQL的JSON类型对象,而GORM默认无法直接将JSON类型自动映射到Go原生的[]string切片,因此抛出unsupported data type: &[]错误。

解决方案

方案一:改用array_agg替代json_agg

PostgreSQL的array_agg函数会直接返回text[]类型(字符串数组),GORM可以直接将其映射到Go的[]string字段,无需额外处理。同时为了避免无匹配关键词时返回NULL,可以用COALESCE函数默认返回空数组。

修改后的SQL语句:

SELECT 
    a.article_id, a.title, a.created_at, a.content, u.name AS author, c.name AS category, sc.name AS sub_category,
    COALESCE(array_agg(k.name), '{}'::text[]) AS keywords, unit.name AS unit
FROM 
    articles a
    LEFT JOIN users u ON a.user_id = u.user_id
    LEFT JOIN categories c ON a.category_id = c.categ_id
    LEFT JOIN sub_categories sc ON a.sub_category_id = sc.sub_categ_id
    LEFT JOIN article_keywords ak ON a.article_id = ak.article_refer_id
    LEFT JOIN keywords k ON ak.keyword_refer_id = k.keyword_id
    LEFT JOIN units unit ON a.unit_id = unit.unit_id
WHERE 
    a.article_id = ? AND
    a.is_posted = true
GROUP BY 
    a.article_id, u.name, c.name, sc.name, unit.name

方案二:自定义类型实现Scanner接口

如果必须保留json_agg(比如需要返回JSON格式的数组),可以通过自定义Go类型并实现sql.Scanner接口,让GORM能够正确解析JSON数据到[]string。

  1. 定义自定义类型:
type StringArray []string
  1. 实现sql.Scanner接口:
import "encoding/json"
import "fmt"

func (sa *StringArray) Scan(value interface{}) error {
    var bytes []byte
    switch v := value.(type) {
    case []byte:
        bytes = v
    case string:
        bytes = []byte(v)
    default:
        return fmt.Errorf("无法解析类型 %T 到 StringArray", value)
    }
    return json.Unmarshal(bytes, sa)
}
  1. 修改结构体字段类型:
type GetArticleByID struct{
    ID              string          `json:"article_id" gorm:"column:article_id"`
    Title           string          `json:"title"`
    Content         string          `json:"content"`
    CreatedAt       time.Time       `json:"created_at"`
    Author          string          `json:"author"`
    Category        string          `json:"category"`
    SubCategory     string          `json:"sub_category"`
    Keywords        StringArray     `json:"keywords"`
    Unit            string          `json:"unit"`
}

这样执行原有的Raw SQL语句时,GORM会自动调用自定义的Scan方法将JSON数组解析为StringArray(本质仍是[]string),正常映射到结构体字段。

内容的提问来源于stack exchange,提问作者Rafi Azzaky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:52:42