GORM Gen数据库转结构体时JSON字段空值写入报错解决方案求助
解决方案:GORM Gen插入JSON字段空值报错问题
针对你遇到的插入记录时未传递JSON字段(other/card)触发Error 3140 (22032): Invalid JSON text错误的问题,以下是几个可行的解决办法:
方案1:修改数据库表,为JSON字段设置默认空JSON对象
直接从数据库层面解决,给JSON字段添加DEFAULT '{}'(或DEFAULT '[]',根据业务需求选择),这样插入时未传值会自动使用默认的合法JSON值,避免报错。
执行SQL修改表:
ALTER TABLE `user_profile` MODIFY COLUMN `other` json NOT NULL DEFAULT '{}' COMMENT 'other personal information', MODIFY COLUMN `card` json NOT NULL DEFAULT '{}' COMMENT 'introduction card';
注:如果业务允许JSON字段为NULL,也可以保留原字段的可空属性,此时插入未传值时数据库会自动填充NULL,不会触发JSON格式错误。
方案2:修改GORM Gen生成的结构体,使用指针类型或设置零值
如果不想修改数据库,可以调整生成的结构体字段:
- 将JSON字段改为指针类型:当未传递值时,字段为
nil,GORM会将其映射为数据库的NULL,而MySQL允许JSON字段为NULL,不会报错。
示例结构体:type UserProfile struct { UUID string `gorm:"column:uuid;type:varchar(50);not null;unique;comment:uuid"` UserID int `gorm:"column:user_id;type:int;not null;primaryKey;comment:user id"` Nickname string `gorm:"column:nickname;type:varchar(20);not null;default:'';comment:nickname"` Age int8 `gorm:"column:age;type:tinyint;not null;default:0;comment:age"` Active bool `gorm:"column:active;type:bool;not null;default:true;comment:whether the user is active"` Rank float32 `gorm:"column:rank;type:float;not null;default:0;comment:user rank"` Other *json.RawMessage `gorm:"column:other;type:json;comment:other personal information"` Card *json.RawMessage `gorm:"column:card;type:json;comment:introduction card"` State string `gorm:"column:state;type:enum('on','off');not null;default:'on';comment:blacklist: off - on"` IsDel int8 `gorm:"column:is_del;type:tinyint;not null;default:0;comment:whether the record is deleted"` CreateTime time.Time `gorm:"column:create_time;type:datetime;not null;default:CURRENT_TIMESTAMP;comment:the time when the record is created"` UpdateTime time.Time `gorm:"column:update_time;type:datetime;not null;default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;comment:the time when the record is updated"` } - 或者在创建结构体实例时,主动给JSON字段设置默认的空JSON对象:
profile := &UserProfile{ // 其他必填字段赋值 Other: json.RawMessage("{}"), Card: json.RawMessage("{}"), } db.Create(profile)
方案3:自定义JSON字段类型,处理空值映射
定义一个自定义类型,实现GORM所需的Scanner和Valuer接口,自动将空值转换为合法的JSON值:
type JSONRaw json.RawMessage // Value 将类型转换为数据库可接受的格式 func (j JSONRaw) Value() (driver.Value, error) { if len(j) == 0 { return []byte("{}"), nil } return json.RawMessage(j).Value() } // Scanner 从数据库读取值并转换为自定义类型 func (j *JSONRaw) Scan(value interface{}) error { return (*json.RawMessage)(j).Scan(value) }
然后在结构体中使用这个自定义类型:
type UserProfile struct { // ... 其他字段 Other JSONRaw `gorm:"column:other;type:json;comment:other personal information"` Card JSONRaw `gorm:"column:card;type:json;comment:introduction card"` // ... 其他字段 }
这样当字段为空时,会自动插入{}作为JSON值,避免格式错误。
内容的提问来源于stack exchange,提问作者jiye zong
相关产品推荐
相关产品推荐

