Function AshPostgres.DataLayer.upsert/3 is undefined or private

I am trying to do an upsert trough the datalayer. Unfortunately i get this error:

DATA LAYER: AshPostgres.DataLayer
EXPORTED?: false
ERROR UPSERT NOT FOUND: AshPostgres.DataLayer
** (UndefinedFunctionError) function AshPostgres.DataLayer.upsert/3 is undefined or private. Did you mean:

      * upsert/4

This is the code behind:

defp upsert_via_data_layer(changeset, identities) do
    Ash.DataLayer.data_layer(changeset.resource)
    |> IO.inspect(label: "DATA LAYER")
    |> function_exported?(:upsert, 4)
    |> IO.inspect(label: "EXPORTED?")

    Ash.DataLayer.upsert(changeset.resource, changeset, identities)
end

I checked the deps and edited the upsert inside Ash.DataLayer like this to get the log shown above

def upsert(resource, changeset, keys, identity \\ nil) do
    changeset = %{changeset | tenant: changeset.to_tenant}
    data_layer = Ash.DataLayer.data_layer(resource)

    if function_exported?(data_layer, :upsert, 4) do
      data_layer.upsert(resource, changeset, keys, identity)
    else
      IO.inspect("UPSERT/4 FOR #{data_layer} NOT IMPLEMENTED")
      data_layer.upsert(resource, changeset, keys)
    end
end

I needed to add import AshPostgres.DataLayer at the top of the file that calls the Ash.DataLayer.upsert
Is this a bug or the intended approach?

Edit: im using ash 3.4.8 and ashpostgres 2.3.1

It is quite strange to be calling the data layer directly like that, but ignoring that for now:

try this:

def upsert(resource, changeset, keys, identity \\ nil) do
    changeset = %{changeset | tenant: changeset.to_tenant}
    data_layer = Ash.DataLayer.data_layer(resource)
    Code.ensure_loaded!(data_layer)

    if function_exported?(data_layer, :upsert, 4) do
      data_layer.upsert(resource, changeset, keys, identity)
    else
      IO.inspect("UPSERT/4 FOR #{data_layer} NOT IMPLEMENTED")
      data_layer.upsert(resource, changeset, keys)
    end
end
1 Like

Yep this works fine!