Upsert Records
Phi performs upserts through the OnConflict API available on create operations.
Rather than exposing a separate Upsert method, Phi allows you to configure how Create, CreateMany, and CreateManyAndReturn behave when a unique constraint is violated.
The examples in this guide use the following Prisma schema:
model User {
id String @id @default(cuid())
name String
email String @unique
password String
bio String?
createdAt DateTime @default(now())
posts Post[]
}OnConflict
OnConflict specifies which unique constraint should be handled if an insert would violate it.
For example, the following handles conflicts on the email unique constraint:
created, err := db.User.Create().
SetName("John Doe").
SetEmail("x@y.com").
SetPassword("secret").
SetBio("super cool bio").
OnConflict(user.Email).Ignore().
Exec(ctx)OnConflict supports the following actions:
Ignore()UpdateNewValues()Update(func(u *phi.UserUpsert) { ... })
Ignore
Ignores records that would violate the specified unique constraint.
created, err := db.User.Create().
SetName("John Doe").
SetEmail("x@y.com").
SetPassword("secret").
SetBio("super cool bio").
OnConflict(user.Email).Ignore().
Exec(ctx)This mirrors SQL's ON CONFLICT DO NOTHING.
UpdateNewValues
Updates every writable field using the values supplied to Create.
created, err := db.User.Create().
SetName("John Doe").
SetEmail("x@y.com").
SetPassword("secret").
SetBio("super cool bio").
OnConflict(user.Email).
UpdateNewValues().
Exec(ctx)This mirrors SQL's ON CONFLICT DO UPDATE SET ... using the inserted values.
Update
Provides full control over the update performed when a conflict occurs.
created, err := db.User.Create().
SetName("John Doe").
SetEmail("x@y.com").
SetPassword("secret").
SetBio("super cool bio").
OnConflict(user.Email).Update(func(u *phi.UserUpsert) {
u.Bio.Set("new bio")
u.Email.Set("new-email")
}).
Exec(ctx)Only the fields specified inside the callback are updated.
Note:
user.Upsertis a type alias forphi.UserUpsert- they are identical. The callback parameter type is generated per model, so you can also write the callback asfunc(u *user.Upsert) { ... }and it will behave exactly the same.
SkipDuplicates
SkipDuplicates is available only on CreateMany and CreateManyAndReturn.
It is equivalent to:
.OnConflict(user.<unique field>).Ignore()and mirrors SQL's ON CONFLICT DO NOTHING.
Supported By
OnConflict is supported by:
SkipDuplicates is supported by: