postgres 的字段是text的json, 如何定义结构体

postgres 的字段是text的json, 如何定义结构体 ostgreSQL 中text类型存 JSON 字符串结构体定义需要自定义类型来实现Scan/Value。以下是完整方案方案一自定义 JSONMap 类型推荐最稳定go复制package main import ( database/sql/driver encoding/json errors fmt gorm.io/gorm ) // JSONMap 自定义类型用于 text 字段存 JSON type JSONMap map[string]interface{} // 存入数据库: map → JSON 字符串 func (m JSONMap) Value() (driver.Value, error) { if m nil { return nil, nil } return json.Marshal(m) } // 从数据库读取: JSON 字符串 → map func (m *JSONMap) Scan(value interface{}) error { if value nil { *m nil return nil } switch v : value.(type) { case []byte: return json.Unmarshal(v, m) case string: return json.Unmarshal([]byte(v), m) default: return errors.New(fmt.Sprintf(无法将 %T 扫描到 JSONMap, value)) } } // 模型定义 type MyModel struct { ID uint gorm:primaryKey Data JSONMap gorm:type:text // PostgreSQL text 字段存 JSON }方案二使用 GORM 的serializer:jsonGORM v2 较新版本go复制type MyModel struct { ID uint gorm:primaryKey Data map[string]interface{} gorm:type:text;serializer:json }⚠️ 需确认你的 GORM 版本支持serializer标签。如果不确定用方案一。方案三如果字段是 PostgreSQL 的json或jsonb类型如果表字段是json/jsonb而非text推荐用pgtype.JSONB配合pgx驱动go复制import github.com/jackc/pgtype type MyModel struct { ID uint gorm:primaryKey Data pgtype.JSONB gorm:type:jsonb }或者继续用自定义类型只需把gorm标签改为type:jsonbgo复制type MyModel struct { ID uint gorm:primaryKey Data JSONMap gorm:type:jsonb // 或 type:json }使用示例go复制// 写入 db.Create(MyModel{ Data: JSONMap{ name: 张三, tags: []string{go, postgres}, meta: map[string]interface{}{ version: 1.0, }, }, }) // 读取 var m MyModel db.First(m) // 访问数据 fmt.Println(m.Data[name]) // 张三 fmt.Println(m.Data[tags].([]interface{})[0]) // go // 也可以序列化回 JSON 字符串 jsonBytes, _ : json.Marshal(m.Data) fmt.Println(string(jsonBytes))快速对比表格字段类型推荐方案说明text存 JSON方案一自定义JSONMap最稳定兼容所有版本json/jsonb方案三pgtype.JSONB或自定义类型利用 PG 原生 JSON 支持建议如果字段已经是text直接用方案一的JSONMap即可无需改表结构。