Hey All!
I’ve got an Ecto.Multi.insert/4
that I’m using with on_conflict: :nothing
. According to Ecto.Repo.insert/2
's docs when a conflict occurs when using on_conflict: :nothing
the resulting schemas id
field should be nil
. However, I’m seeing an id
field with a value. When I remove the :on_conflict
option I get a unique constraint error. When I get the count of number of records it does not change from before to after the transaction. So the record doesn’t seem to actually be getting created even though an id
value is present.
Our primary keys are UUID. When we define a schema we set the @primary_key
value to { :id, :binary_id, autogenerate: true }
. So the database should be the one generating the keys.
Kind of at a loss.
Thanks!
The docs say:
id
will be nil if the field is autogenerated by the database and no insert happened.
autogenerate: true
is database dependent. For SQL databases, it is generated by Ecto and not the database. Luckily I just read an article that hows how to use pgcrypto to generate it in the DB: Ecto Tips: UUID Boilerplate, Docs, and Composing Changesets · Bernheisel
1 Like
Thanks for the recommended reading.
Just FYI, we’re using Postgres with the uuid-ossp
extension. All of our primary key definitions look like this.
add :id, :binary_id, default: fragment("uuid_generate_v4()"), primary_key: true
I’ll read the article you provided and see if I can come up with anything.
Thanks for the help!
Reading through Ecto.Schema
’s docs I saw this.
If you use the :id
type with :autogenerate
, it means the database will be responsible for auto-generation of the id.
Is this behavior different for :binary_id
? I think I assumed :autogenerate
set to true
would make the database and not Ecto responsible for auto-generating the id.
After reading the article you provided I was able to figure it out.
Setting :read_after_writes
to true
instead of :autogenerate
did the trick. Was confused by the documentation.
Thank you!
1 Like