为了账号安全,请及时绑定邮箱和手机立即绑定

GORM 创建可能已经存在的记录

GORM 创建可能已经存在的记录

Go
呼啦一阵风 2023-07-17 16:33:14
我在 Go 应用程序中使用gorm和 postgres。我想在数据库中创建一个新用户,但该用户很可能已经存在。如果是这样,我不想对数据库做任何事情,但我想了解它,以便我可以告诉用户。好消息是,这已经是事实gorm.Create(..)了。尝试使用重复的唯一键创建记录将返回错误。有两个问题:我想要更好的错误消息。我想编写面向用户的自定义错误消息,这些消息与“此电子邮件地址已存在”和“存在实际内部错误”不同。除了尝试解析似乎容易出现错误的错误字符串之外,我不知道如何区分这两个事件Create()。我不想让我的日志变得混乱。Create()使用已存在的对象进行调用会将错误消息记录到标准输出。我真的不认为这是一个“错误”,因为我预计它会发生,而且我不想用一堆这样的警告淹没我的日志。我知道我可以使用事务首先检查具有给定 id 的用户,然后创建它们(如果尚不存在),但似乎应该有一个更简单的解决方案来解决这样的基本问题。你应该怎么做?我目前正在这样做:func (self databaseWrapper) CreateUser(user *User) error {    db := self.db    db.NewRecord(*user)    err := db.Create(user).Error    if err != nil {        if db.Where(user.ID).Take(&User{}).Error == nil {            return fmt.Errorf("A user already exists with id %v", user.ID)        }        if db.Where(User{Email: user.Email}).Take(&User{}).Error == nil {            return fmt.Errorf("A user already exists with the given email address: %v", user.Email)        }        return fmt.Errorf("Error creating user")    }    return nil}这有点低效并且给出了丑陋的输出:go test(/home/quinn/workspace/aev/sensor/backend/server/database.go:125)[2019-09-01 14:45:40]  pq: duplicate key value violates unique constraint "users_pkey"(/home/quinn/workspace/aev/sensor/backend/server/database.go:125)[2019-09-01 14:45:40]  pq: duplicate key value violates unique constraint "uix_users_email"PASSok          3.215s即使一切都按预期进行。
查看完整描述

3 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

要添加到前面的答案中,当前您还可以使用类似的方法来检查错误代码(在示例中:检查重复的键)。


import "github.com/jackc/pgx"

...

func isDuplicateKeyError(err error) bool {

    pgErr, ok := err.(pgx.PgError)

    if ok {

        // unique_violation = 23505

        return pgErr.Code == "23505"


    }

    return false

}


查看完整回答
反对 回复 2023-07-17
?
MM们

TA贡献1886条经验 获得超2个赞

lib/pq是标准的 postgres 驱动程序。如果出现查询错误,它将返回一个pq.Error对象(即使您使用的是 GORM)。该pq.Error类型有一个Code字段,您可以检查该字段以查看错误原因。


if err, ok := err.(*pq.Error); ok && err.Code.Name() == "unique_violation" {

    // handle error

}

查看完整回答
反对 回复 2023-07-17
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

在 Gorm v1.21 中,我相信你可以...


配置记录器

import (

  gormLogger "gorm.io/gorm/logger"

)


func main() {

  db, err := gorm.Open(

    sqlite.Open("test.db"),

    &gorm.Config{

      Logger: gormLogger.New(

        log.New(os.Stdout, "\r\n", log.LstdFlags),

        gormLogger.Config {

          LogLevel: gormLogger.Silent,

          // IgnoreRecordNotFoundError: true,

        },

      ),

    },

  )

}

https://gorm.io/docs/logger.html#Logger

捕获并打印您自己的错误消息

result := db.Where("email = ?", "test@test.com").Take(&user)


if !errors.Is(result.Error, gorm.ErrRecordNotFound) {

  fmt.Println("record already exists")

  // Or use a logger

  // logger.Info("record already exists")

}

https://gorm.io/docs/query.html#Retrieving-a-single-object

https://gorm.io/docs/error_handling.html#ErrRecordNotFound

https://github.com/go-gorm/gorm/blob/master/errors.go


查看完整回答
反对 回复 2023-07-17
  • 3 回答
  • 0 关注
  • 143 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信