我從 API 中提取資料。拉取結果是結構陣列,每個陣列包含 100 個元素。我用來將它們插入資料庫的代碼是:
func (ACUpdater) InsertToTable(rawData *models.Contacts, table *gorm.DB) {
for i := 0; i < len(rawData.Results); i {
temp := models.ACQ_report{
ID : "", //to be created later by hashing below data fields
RecordID: rawData.Results[i].ID,
FirstName: rawData.Results[i].Properties.Firstname,
LastName: rawData.Results[i].Properties.Lastname,
Email: rawData.Results[i].Properties.Email,
PhoneNumber: rawData.Results[i].Properties.Phone,
ContactOwner: rawData.Results[i].Properties.HubspotOwnerID,
CompanyName: rawData.Results[i].Properties.Company,
}
temp.ID = hashContactRecord(&temp)
table.Create(&temp)
fmt.Println(&temp)
fmt.Println(i)
}
}
我使用資料欄位的散列作為表的主鍵,因此如果這些資料欄位中的任何一個發生變化,散列也會發生變化。這樣,我可以將更改的記錄附加到現有表中,而不必擔心重復的主鍵。
INSERTING
問題是,在GORM 出現 1 個重復的主鍵錯誤后,上述功能完全“放棄” 。如果要插入資料庫的第一條記錄是重復的,那么tx.Created(&temp)
仍然會運行,但它沒有插入更改的記錄。好像tx.Create()
在第一次重復主鍵錯誤之后就放棄了。
如何解決這種行為?
uj5u.com熱心網友回復:
這里的第一個問題可能掩蓋了實際的根本原因,是您沒有檢查INSERT
是否回傳錯誤。你會這樣做:
result := tx.Create(&temp)
if result.Error != nil {
// handle it somehow
}
如果您這樣做并檢查錯誤,您可能會看到以下幾點:
錯誤:重復鍵值違反唯一約束
即使您還看到下面的錯誤,您也可能會看到這一點。在這種情況下,您的 INSERT 正在執行,但失敗了。如果您沒有看到任何其他錯誤并且只列印一次,那么您可能傳入了一個鏈接到資料庫會話的 gorm.DB 句柄,并且將在第一個錯誤時失敗。
例如,如評論中所述,如果您將結果傳遞db.Table("my_table")
給此方法,則將出現上述情況。要修復它,只需傳遞db
or db.NewSession()
,并更新您的方法以指定 Table (或 Model,更像 Gorm):
result := db.Table("my_table_name").Create(&temp)
if result.Error != nil {
// ...
}
選項 2:錯誤:當前事務被中止,命令被忽略,直到事務塊結束
如果你看到這個,這意味著你的方法正在事務中運行它的插入。事實證明對您而言并非如此,但是由于這是一個通用論壇,因此我將在此處保留此內容和以下說明:在 Postgres 中,如果事務中的任何陳述句失敗,則除了 ROLLBACK 之外,您無法執行任何其他陳述句.
要解決此問題,您有幾個選擇:
在嘗試插入之前進行更多的資料驗證,直到您可以可靠地預期每次插入都會成功。您還可以使用 Gorm 的批量插入功能通過這種方法優化插入。
不要使用事務。如果您對跳過的行沒問題,并且不擔心重復,這是一個合理的選擇。
使用SAVEPOINTs。在 Postgres 中,SAVEPOINT 類似于事務中的檢查點,您可以回滾到它而不是回滾整個事務,這幾乎是您想要的:
tx.SavePoint("sp1") // SAVEPOINT sp1;
result := tx.Create(&temp)
if result.Error != nil {
tx.RollbackTo("sp1") // ROLLBACK TO sp1;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/508325.html
標籤:PostgreSQL 去 戈戈姆