You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gorm仅插入Wallet条目,其余AccountType未创建的问题咨询

问题分析与解决方案

嘿,我一眼就揪出问题所在了——你对GORM的First方法的用法理解跑偏啦!

你当前写的db.First(&acccountTypeModelWallet)并不是按照你设置的Type和Name字段去查询匹配的记录,而是会直接查询表中的第一条记录,然后把这条记录的所有字段值覆盖到你的结构体变量里。咱们顺着你的代码走一遍就能明白为啥只有Wallet被创建了:

  • 第一次执行Wallet的逻辑时,数据库是空的,db.First找不到任何记录,触发RecordNotFound(),所以成功创建了Wallet条目。
  • 轮到Bank Account的逻辑时,数据库里已经有了Wallet这条记录,db.First(&acccountTypeModelBankAccount)会把Wallet的Type和Name直接赋值给你的acccountTypeModelBankAccount变量,这时候RecordNotFound()返回false,自然就跳过了创建步骤。
  • Exchange Account的逻辑也是完全一样的道理,所以这两个条目都不会被创建。

修复方案

有两种靠谱的方式解决这个问题:

方式1:明确指定查询条件

用Where搭配First,告诉GORM你要根据Type(或者Type+Name)去查询记录:

acccountTypeModelWallet := accounttypes.AccountType{Type: "wallet", Name: "Wallet"}
if db.Where(&acccountTypeModelWallet).First(&acccountTypeModelWallet).RecordNotFound() {
    fmt.Println("Account Type `Wallet` not found. Creating..")
    err := db.Create(&acccountTypeModelWallet).Error
    if err != nil {
        return false, err
    }
}

// Bank Account 部分同理修改
acccountTypeModelBankAccount := accounttypes.AccountType{Type: "bankaccount", Name: "Bank Account"}
if db.Where(&acccountTypeModelBankAccount).First(&acccountTypeModelBankAccount).RecordNotFound() {
    fmt.Println("Account Type `Bank Account` not found. Creating..")
    err := db.Create(&acccountTypeModelBankAccount).Error
    if err != nil {
        fmt.Println(err)
        return false, err
    }
}

// Exchange Account 部分同理修改
acccountTypeModelExchange := accounttypes.AccountType{Type: "exchange", Name: "Exchange Account"}
if db.Where(&acccountTypeModelExchange).First(&acccountTypeModelExchange).RecordNotFound() {
    fmt.Println("Account Type `Exchange Account` not found. Creating..")
    err := db.Create(&acccountTypeModelExchange).Error
    if err != nil {
        return false, err
    }
}

如果你想更精准地指定查询字段(比如只按Type查询),也可以写成:

if db.First(&acccountTypeModelWallet, "type = ?", "wallet").RecordNotFound() {
    // 创建逻辑
}

方式2:用FirstOrCreate简化代码

GORM提供了FirstOrCreate方法,直接一步完成“查询不存在则创建”的逻辑,比手动判断更简洁也更不容易出错:

// Wallet 部分
acccountTypeModelWallet := accounttypes.AccountType{Type: "wallet", Name: "Wallet"}
// 第二个参数是查询条件,按Type字段匹配
db.FirstOrCreate(&acccountTypeModelWallet, accounttypes.AccountType{Type: "wallet"})

// Bank Account 部分
acccountTypeModelBankAccount := accounttypes.AccountType{Type: "bankaccount", Name: "Bank Account"}
db.FirstOrCreate(&acccountTypeModelBankAccount, accounttypes.AccountType{Type: "bankaccount"})

// Exchange Account 部分
acccountTypeModelExchange := accounttypes.AccountType{Type: "exchange", Name: "Exchange Account"}
db.FirstOrCreate(&acccountTypeModelExchange, accounttypes.AccountType{Type: "exchange"})

这个方法会先根据第二个参数的条件查询记录,找到就把数据赋值给第一个参数的结构体;找不到就用第一个参数的结构体创建新记录,完美适配你的需求。

内容的提问来源于stack exchange,提问作者Tino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:45:52