B1C*_*0PS 6 postgresql go go-gorm
我在我的 Go 应用程序中使用gorm和 postgres。
我想在数据库中创建一个新用户,但该用户很有可能已经存在。如果是这样,我不想对数据库做任何事情,但我想知道它以便我可以告诉用户。
好消息是,这已经发生了gorm.Create(..)。尝试使用重复的唯一键创建记录将返回错误。有两个问题:
Create()似乎容易出错的错误字符串之外,我不知道如何区分这两个事件。Create()使用已存在的对象进行调用会将错误消息记录到 stdout。我并不真的认为这是一个“错误”,因为我期待它发生,而且我不想用一堆这些警告淹没我的日志。我知道我可以使用事务首先检查具有给定 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
}
Run Code Online (Sandbox Code Playgroud)
这有点低效并给出了丑陋的输出:
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
Run Code Online (Sandbox Code Playgroud)
即使一切都按预期进行。
要添加到前面的答案中,当前您还可以使用类似的方法来检查错误代码(在示例中:检查重复的键)。
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
}
Run Code Online (Sandbox Code Playgroud)
在 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,
},
),
},
)
}
Run Code Online (Sandbox Code Playgroud)
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")
}
Run Code Online (Sandbox Code Playgroud)