GORM创建可能已经存在的记录 [英] GORM create record that might already exist

查看:118
本文介绍了GORM创建可能已经存在的记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Go应用中将 gorm 与postgres一起使用.

我想在数据库中创建一个新用户,但是该用户很有可能已经存在.如果是这样,我不想对数据库做任何事情,但是我想知道这一点,以便告诉用户.

好消息是,这已经是 gorm.Create(..)可以.尝试使用重复的唯一键创建记录将返回错误.有两个问题:

  1. 我想要更好的错误消息.我想编写面向用户的自定义错误消息,该错误消息的此电子邮件地址已存在"与发生实际的内部错误"不同.除了尝试解析 Create()返回的错误字符串(似乎容易出错)之外,我不知道如何区分这两个事件.
  2. 我不想弄乱我的日志.使用已存在的对象调用 Create()会将错误消息记录到stdout.我真的不认为这是一个错误",因为我期望它会发生,并且我也不想一堆这样的警告来淹没我的日志.

我知道我可以使用事务来首先检查具有给定id的用户,然后在不存在该ID的情况下创建它们,但是似乎应该为这种基本问题提供一个更简单的解决方案.你应该怎么做?


我目前正在这样做:

  func(self databaseWrapper)CreateUser(user * User)错误{db:= self.dbdb.NewRecord(* user)错误:= db.Create(用户).错误如果err!= nil {if db.Where(user.ID).Take(& User {}).Error == nil {返回fmt.Errorf(用户已经存在,ID为%v",user.ID)}if db.Where(User {Email:user.Email}).Take(& User {}).Error == nil {return fmt.Errorf(用户已经存在,具有给定的电子邮件地址:%v",user.Email)}返回fmt.Errorf(创建用户时出错")}返回零} 

效率低下,输出难看:

 进行测试(/home/quinn/workspace/aev/sensor/backend/server/database.go:125)[2019-09-01 14:45:40] pq:重复的键值违反了唯一约束"users_pkey"(/home/quinn/workspace/aev/sensor/backend/server/database.go:125)[2019-09-01 14:45:40] pq:重复的键值违反了唯一约束"uix_users_email"经过好的3.215s 

即使一切都按预期进行.

解决方案

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

  import" github.com/jackc/pgx"...func isDuplicateKeyError(err error)bool {pgErr,好的:=错误(pgx.PgError)如果可以,{//unique_violation = 23505return pgErr.Code =="23505"}返回假} 

I'm using gorm with postgres in my Go app.

I want to create a new user in the database, but there is a good chance that that user will already exist. If so, I want to not do anything with the database, but I want know about it so I can tell the user.

The good news is, that's already what gorm.Create(..) does. Trying to create a record with a duplicate unique key will return an error. There are two problems:

  1. I want better error messages. I want to write custom user-facing error messages that are different for "This email address already exists" than "There was an actual internal error." I don't know how to diferentiate between these two events other than trying to parse the error string returned by Create() which seems bug prone.
  2. I don't want to clutter my logs. Calling Create() with an object that already exists logs an error message to stdout. I don't really consider this an "error" since I was expecting it to happen and I don't want to flood my logs with a bunch of these warnings.

I know I could use a transaction to first check for a user with the given id and then create them if one does not already exist, but it seems like there should be a simpler solution to such a basic thing. How are you supposed to do this?


I'm currently doing this:

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
}

Which is a little inefficient and gives the ugly output:

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"
PASS
ok          3.215s

even when everything worked as expected.

解决方案

To add to the previous answer, currently you can also use something like this to check for error codes (in the example: checking for duplicate keys).

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
}

这篇关于GORM创建可能已经存在的记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆