最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

go - How can I use the gorm library to bulk upsert records into a postgres DB and return the IDs of those that are inserts and n

programmeradmin3浏览0评论

Although this can be done with a raw query, I would like to bulk insert a small number of records and handle upsert conflicts through the gorm Create API. I need to return the IDs of records that are inserted and not updated.

        RETURNING CASE WHEN xmax = 0 THEN id ELSE NULL END

However, the library appears to limit the returning clause to contain only columns.

Rather than make another query to the DB, I'd prefer to do this in one round trip. Is there another usage of the API that would enable this use case through gorm, or must I resort to a raw query here?

This related question assumes that the existing records are populated before the upsert query. There is nothing on the returned structs to distinguish inserted from updated.

Although this can be done with a raw query, I would like to bulk insert a small number of records and handle upsert conflicts through the gorm Create API. I need to return the IDs of records that are inserted and not updated.

        RETURNING CASE WHEN xmax = 0 THEN id ELSE NULL END

However, the library appears to limit the returning clause to contain only columns.

Rather than make another query to the DB, I'd prefer to do this in one round trip. Is there another usage of the API that would enable this use case through gorm, or must I resort to a raw query here?

This related question assumes that the existing records are populated before the upsert query. There is nothing on the returned structs to distinguish inserted from updated.

Share Improve this question asked Feb 17 at 3:25 Anthony OAnthony O 67210 silver badges28 bronze badges
Add a comment  | 

1 Answer 1

Reset to default -1

Gorm does not provide a method to directly return different data based on inserted or updated info of record. A raw query is necessary for this type of behavior.

type User struct {
    ID    uint   `gorm:"primaryKey"`
    Name  string
    Email string `gorm:"unique"`
}

create a slice of records to upsert

users := []User{
    {Name: "John Doe", Email: "[email protected]"},
    {Name: "Jane Smith", Email: "[email protected]"},
}

example:

var insertedIDs []uint

//  INSERT ... ON CONFLICT ... handles the upsert logic
query := `
    INSERT INTO users (name, email)
    VALUES ($1, $2), ($3, $4)
    ON CONFLICT(email) DO UPDATE
    SET name = EXCLUDED.name
    RETURNING id
`

// then execute a RAW query
rows, err := db.Raw(query, users[0].Name, users[0].Email, users[1].Name, users[1].Email).Rows()
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

for rows.Next() {
    var id uint
    if err := rows.Scan(&id); err != nil {
        log.Fatal(err)
    }
    insertedIDs = append(insertedIDs, id)
}

if err := rows.Err(); err != nil {
    log.Fatal(err)
}

fmt.Println("Inserted IDs:", insertedIDs)

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论