使用gorm框架,map作为参数创建记录报错


for _, answer := range answers {
            answer["pid"] = pid
            fmt.Println(answer)
            err := tx.Table(tablePaperQuestion).Create(&answer).Error
            if err != nil {
                fmt.Println("新建题目失败", err)
                return 0, err
            }
        }

answers 是一个map切片,代码中的输出如下
map[answer:A blk_correct:0 blk_total:0 duration:120 id:22 is_correct:true is_pass:false is_sbj_question:false pid:3128078540406618 sbj_rate_score:-1 score:10 source:0 start_at:1672316400]

新建题目失败 Error 1062: Duplicate entry '0' for key 'PRIMARY'

表中主键为id,为啥似乎map中的id字段没有去对应表中的id字段,还是其它什么原因呢?为啥有上面这个报错啊

引用 皆我百晓生 小程序回复内容作答:
根据报错信息来看,问题可能出在id字段上。根据代码片段,你将map切片中的每个元素传递给了Create方法,并且期望gorm可以将该map结构体映射到相应的表结构体中。

关于这个问题,首先需要明确的是,gorm默认会将结构体中的字段映射到表中的字段名。如果结构体中的字段名与表中的字段名不一致,gorm可以通过struct tag来进行映射。

另外,创建记录时,gorm通常会将自增的主键字段设置为0,并且在数据库中生成唯一的主键。

根据你提供的输出信息和报错信息,推测可能有以下几种原因导致报错:

  1. id字段的类型不符合自增主键的要求(一般为int或int64类型)。
  2. id字段没有被选中作为自增主键。
  3. 表中已经存在了id为0的记录,并且没有设置自增。

解决方法:

  1. 确保id字段的类型符合自增主键的要求。
  2. 使用gorm的AutoMigrate方法,确保表结构与模型结构一致,包括id字段的定义和自增设置。
  3. 检查数据库中的重复记录,删除重复的id为0的记录,或者将id字段修改为能保证唯一性的值。

如果以上方法不奏效,请提供完整的代码和表结构定义,以便更好地帮助你解决问题。

【以下回答由 GPT 生成】

问题原因:报错信息显示为"Error 1062: Duplicate entry '0' for key 'PRIMARY'",即主键重复错误。根据代码和输出结果分析,可以得出以下可能的原因和解决方案:

  1. id字段重复:根据代码和输出,可以看到map中的id字段为22,但是报错信息中显示为0。可能是在创建记录时,没有正确给id字段赋值,导致默认为0,进而引发了主键重复错误。

解决方案:可以在创建记录之前,给answer map中的id字段赋予唯一的值,避免重复。

for _, answer := range answers {
    answer["pid"] = pid
    answer["id"] = generateUniqueID()  // 生成唯一的id值
    fmt.Println(answer)
    err := tx.Table(tablePaperQuestion).Create(&answer).Error
    if err != nil {
        fmt.Println("新建题目失败", err)
        return 0, err
    }
}

其中,generateUniqueID()可以是一个自定义的函数,根据具体需求生成唯一id的方式。

  1. 数据库问题:除了给answer map赋予正确的id值之外,还有可能是数据库表的配置问题。例如,表中的id字段设置为自增主键,但映射到代码的时候没有正确设置。

解决方案:检查数据库表的定义,确保id字段为自增主键,并在代码中使用相应的标记来映射字段,例如使用gorm:"primary_key"

type Answer struct {
    ID        uint `gorm:"primary_key"`
    // 其他字段
}

如果以上解决方案都没有解决问题,请提供更多相关的代码和错误信息以供进一步分析。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^