【发布时间】:2022-01-13 21:26:17
【问题描述】:
当我尝试将两个或多个寄存器插入 for 循环时出现此错误,第一个工作正常但随后出现错误,数据库是新的,我已经重新创建了很多次
pq: duplicate key value violates unique constraint \"movements_pkey\
我有我的动作模型
type Movement struct {
ID int `gorm:"primary_key" json:"id"`
Amount float32 `json:"amount"`
FkType *int `gorm:"column:fk_type" json:"fk_type"`
Type Type `gorm:"foreignkey:FkType"`
FkIncome int `gorm:"column:fk_income" json:"fk_income"`
Income Incoming `gorm:"foreignkey:FkIncome"`
FkOrder *int `gorm:"column:fk_order" json:"fk_order,omitempty"`
CreatedAt *time.Time `json:"created_at"`
}
这里是我在 for 循环中调用函数以保存在数据库 (MovementCreate) 中的地方,第一个总是成功创建,但第二个给我这个错误,尝试创建新记录但显然 postgresql 采取相同的最后一个ID
func (w *WebServices) CreateMovementMoneyOut(dataMovement *validators.MovementValidator) ([]models.IncomingResult, error) {
nameFile := "Movement Services"
dataWallet, err := w.wallet.FindWalletByCustomerID(dataMovement.FKCustomer)
if err != nil {
utils.LogService(nameFile, "Wallet Find", err.Error(), "error")
return nil, err
}
if (dataWallet.Amount <= 0) || !(*dataMovement.FkType == 2) {
utils.LogService(nameFile, "Wallet Update", "Insufficients funds", "error")
return nil, fmt.Errorf("Insufficients funds")
}
incomingUpdate, err := w.incoming.UpdateIncomingsByFkWallet(&dataWallet.ID, *dataMovement.Amount)
var movement models.Movement
for _, val := range incomingUpdate {
movement.Amount = val.Amount
movement.FkIncome = val.ID
movement.FkType = dataMovement.FkType
movement.FkOrder = dataMovement.FkOrder
_, err := w.movement.MovementCreate(&movement)
if err != nil {
utils.LogService(nameFile, "CreateMovementMoneyOut", err.Error(), "error")
return nil, err
}
}
newAmount, err := w.incoming.CalculateWalletAmount(&dataWallet.ID)
if err != nil {
utils.LogService(nameFile, "Wallet Update", err.Error(), "error")
}
_, err = w.wallet.WalletUpdateAmount(dataWallet, newAmount)
if err != nil {
utils.LogService(nameFile, "Wallet Update", err.Error(), "error")
return nil, err
}
return incomingUpdate, nil
}
保存到数据库时在此处
func (s *WalletService) MovementCreate(data *Movement) (*Movement, error) {
result := s.Create(data)
return data, result.Error
}
控制台报错的完整响应是这样的
2021/12/08 20:57:18 /usr/src/app/pkg/datalayers/models/movement.go:45 pq: duplicate key value violates unique constraint "movements_pkey"
[1.249ms] [rows:0] INSERT INTO "movements" ("amount","fk_type","fk_income","fk_order","created_at","id") VALUES (1000.000000,2,7,1,'2021-12-08 20:57:16.173',16) RETURNING "id"
16是循环中第一次迭代成功创建的最后一个id,下一次迭代尝试使用相同的id但新记录的数据正确
【问题讨论】:
-
上面代码中的motion.ID分配在哪里。请确保每次在循环内都将其覆盖,或者您可以在循环内声明移动变量以确保不会继续前一个循环的数据。
-
WalletService.Create中发生了什么。此外,由于您的 id 是一个 int - 我猜您可能还需要结构中的 autoIncrement 字段标记 - 不过请先检查您的表详细信息(\d tablename)。如果您自己处理,请忽略。
标签: postgresql go go-gorm