How to use custom_index as identity

Hey, is there a way to use a custom index as a identity for upsert?

For example, I have a resource that has two nullable fields.

I want to create an upsert using them, but creating a identity with them will make null values distinctable one from another.

The solution would to use a custom index, but I can’t figure out how to use in the upsert

You’re right that it doesn’t look like that is supported at the moment.

My suggestion for a work-around would be to add a custom_index to your resource and make a manual create action that performs the upsert you require directly with Ecto.

Hope that helps!

Can you not create an identity using both attributes?

From the docs, full_name includes two attributes:

identities do
  identity :full_name, [:first_name, :last_name]
  identity :email, [:email]
end

Then the upsert action uses the options:
[upsert?: true, upsert_identity: :full_name]

I’m curious why that would not work.

You can definitely create a composite identity - I think that @sezaru’s problem is more about the possible nulliness of values.

Ok in that case it sounds like they may not actually have an identity to anchor an upset to in principle.

The other possibility is perhaps they have two different use cases with two different upsert actions and a separate identity used in each case?

Yes, it is related to null being distinct by default in postgres.

I did create a PR to add support for the nulls_distinct ecto option when creating the index for custom indexes here feat: Add support for nulls_distinct in custom indexes by sezaru · Pull Request #175 · ash-project/ash_postgres · GitHub

But, I realize afterwards that I cannot use the custom index as a identity, and, of course, the identity itself doesn’t have support for that option as-well.

Yeah, I think the best option at this stage is to do a manual action and I’m sure that @zachdaniel will have some opinions to share when he gets back from his holiday.

Yep, that’s what i did for now hehe.