使用GORM时出现‘unsupported data type: &[]’错误的原因及修复方法
修复GORM扫描PostgreSQL整数数组时的"unsupported data type: &[]"错误
错误核心原因是GORM默认未识别pq.Int64Array类型的数据库转换逻辑,导致执行Scan时无法将PostgreSQL的int8[]类型映射到结构体字段。以下是三种可行的修复方案:
方案一:显式注册pq数组类型到GORM
在数据库初始化阶段,将pq.Int64Array注册为GORM支持的PostgreSQL数组类型:
import ( "gorm.io/driver/postgres" "gorm.io/gorm" "github.com/lib/pq" ) func NewDB(dsn string) (*gorm.DB, error) { db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { return nil, err } // 注册pq.Int64Array对应PostgreSQL的int8[]类型 db.RegisterDataType("int8[]", pq.Int64Array{}) return db, nil }
注册后,原有的TrackMatches结构体无需修改,重新执行查询即可正常扫描数组。
方案二:自定义数组类型实现Scanner/Valuer接口
如果不想依赖lib/pq的自动注册,可以自定义数组类型,实现数据库驱动的Scanner和Valuer接口,确保GORM能正确转换:
import "database/sql/driver" import "github.com/lib/pq" // 自定义Int64Array类型 type Int64Array []int64 // 实现Scanner接口,从数据库读取数据 func (a *Int64Array) Scan(value interface{}) error { return pq.Array(a).Scan(value) } // 实现Valuer接口,向数据库写入数据 func (a Int64Array) Value() (driver.Value, error) { return pq.Array(a).Value() }
修改TrackMatches结构体的字段类型,并指定数据库类型:
type TrackMatches struct { HtmlTextStructureHash string `json:"htmltext_structure_hash" gorm:"column:htmltext_structure_hash"` TrackIds Int64Array `json:"track_ids" gorm:"column:track_ids;type:int8[]"` }
方案三:手动扫描并转换结果
作为兜底方案,可以先将数组字段扫描为字节数组,再手动转换为pq.Int64Array:
func (db *DB) GetAllTracks(ctx context.Context) ([]TrackMatches, error) { // 定义临时结构体接收原始结果 var tempResults []struct { HtmlTextStructureHash string `gorm:"column:htmltext_structure_hash"` TrackIdsBlob []byte `gorm:"column:track_ids"` } qry := "select triages.htmltext_structure_hash as htmltext_structure_hash, array_agg(tracks.id) as track_ids from tracks cross join unnest(tracks.triage_ids) as i(item) join triages on triages.triage_id = i.item group by triages.htmltext_structure_hash;" if err := db.Raw(qry).Scan(&tempResults).Error; err != nil { return nil, err } // 转换为目标结构体 var results []TrackMatches for _, temp := range tempResults { var trackIds pq.Int64Array if err := trackIds.Scan(temp.TrackIdsBlob); err != nil { return nil, err } results = append(results, TrackMatches{ HtmlTextStructureHash: temp.HtmlTextStructureHash, TrackIds: trackIds, }) } return results, nil }
内容的提问来源于stack exchange,提问作者cylus
相关产品推荐
相关产品推荐

