gorm icon indicating copy to clipboard operation
gorm copied to clipboard

如何使用 Updates 方法无法保存字段类型为 map 的数据

Open tint opened this issue 2 years ago • 4 comments
trafficstars

Your Question

我没有办法保存字段类型为 map 的数据

type ConfigUpsertRequest struct {
	ID          uint           `json:"id"          xml:"id"          form:"id" param:"id"`
	GroupID     uint           `json:"group_id"    xml:"group_id"    form:"group_id"`
	Name        string         `json:"name"        xml:"name"        form:"name"`
	Title       string         `json:"title"       xml:"title"       form:"title"`
	Description string         `json:"description" xml:"description" form:"description"`
	DataType    string         `json:"data_type"   xml:"data_type"   form:"data_type"`
	Attributes  map[string]any `json:"attributes"  xml:"attributes"  form:"attributes"`
	Sort        int32          `json:"sort"        xml:"sort"        form:"sort"`
}

func (c *ConfigUpsertRequest) ToMap() map[string]any {
	return map[string]any{
		"group_id":    c.GroupID,
		"name":        c.Name,
		"title":       c.Title,
		"description": c.Description,
		"data_type":   c.DataType,
		"attributes":  c.Attributes,
		"sort":        c.Sort,
	}
}

// 业务逻辑
request := &ConfigUpsertRequest{
	"title": "添加菜单",
	“attributes”: map[string]any{},
}
err := db.
	Model(&entities.Config{}).
	Where("id", 1).
	Updates(request.ToMap()).
	Error

执行结果报错

 [sql: converting argument $1 type: unsupported type map[string]interface {}, a map]

image

tint avatar Nov 01 '23 04:11 tint

那如果数据是map类型的,期望保存成数据库中什么数据类型呢?

ismdeep avatar Nov 02 '23 05:11 ismdeep

@tint Oh, you cannot use a map as SQL value directly, and it's not Gorm's issue, it's what Golang required. Please see the document of sql.Scanner and driver.Valuer: 1, sql.Scanner: a custom type must implement this so that it can convert from sql values. 2, driver.Valuer: a custom type must implement this so that it can convert itself to sql values. if you want to use a map as a SQL field, you must implement driver.Valuer method, check gorm's JSONMap struct for example: https://github.com/go-gorm/datatypes/blob/master/json_map.go

ivila avatar Nov 02 '23 06:11 ivila

那如果数据是map类型的,期望保存成数据库中什么数据类型呢?

关键是我已经指定了模型 db.Model(&entities.Config{}),模型里面指定了序列化方式为 json。

tint avatar Nov 04 '23 00:11 tint

那如果数据是map类型的,期望保存成数据库中什么数据类型呢?

关键是我已经指定了模型 db.Model(&entities.Config{}),模型里面指定了序列化方式为 json。

@tint 不是Model的问题,是你的attributes字段是个map

ivila avatar Nov 04 '23 04:11 ivila