elixir-ecto / ecto

A toolkit for data mapping and language integrated query.
https://hexdocs.pm/ecto
Apache License 2.0
6.13k stars 1.43k forks source link

Ecto.Changeset check_constraint function not working as expected #4415

Closed Artexis10 closed 4 weeks ago

Artexis10 commented 3 months ago

Elixir version

1.15.6

Database and Version

PostgreSQL 11.12

Ecto Versions

3.10.3

Database Adapter and Versions (postgrex, myxql, etc)

0.17.3

Current behavior

Here is the implementation:

Migration:

    create constraint("notes", :entity_id_entity_code,
             check: "entity_id IS NOT NULL OR entity_code IS NOT NULL",
             prefix: "public"
           )

Schema: check_constraint(:entity_id, name: :entity_id_entity_code)

Following the documentation of check_constraint, this is the error that occurs:

** (Ecto.ConstraintError) constraint error when attempting to insert struct:

         * "entity_id_entity_code" (check_constraint)

     If you would like to stop this constraint violation from raising an
     exception and instead add it as an error to your changeset, please
     call `check_constraint/3` on your changeset with the constraint
     `:name` as an option.

     The changeset has not defined any constraint.

Stacktrace:

stacktrace:
       (ecto 3.10.3) lib/ecto/repo/schema.ex:804: anonymous fn/4 in Ecto.Repo.Schema.constraints_to_errors/3
       (elixir 1.15.6) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2
       (ecto 3.10.3) lib/ecto/repo/schema.ex:788: Ecto.Repo.Schema.constraints_to_errors/3
       (ecto 3.10.3) lib/ecto/repo/schema.ex:769: Ecto.Repo.Schema.apply/4
       (ecto 3.10.3) lib/ecto/repo/schema.ex:377: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
       (ecto 3.10.3) lib/ecto/repo/schema.ex:273: Ecto.Repo.Schema.insert!/4

Expected behavior

The expectation is that the Ecto.ConstraintError is handled and does not raise an exception. Currently, it does not and suggests that to handle this, the check_constraint function needs to be defined on the changeset, which it already is.

josevalim commented 3 months ago

Can you please provide the full code?

The fact the error message does not list your constraint seems to indicate that the constraint is not effectively stored in the changeset. Maybe you are setting the constraint and then discarding the changeset (or returning another changeset).

Artexis10 commented 3 months ago

I am unable to provide more code as there would be a confidentiality issue. In the code, I am returning the same changeset, so it is unlikely to be that.

Artexis10 commented 3 months ago

Are you able to replicate the issue?

ericmj commented 3 months ago

You need to do provide us a way to replicate the issue. We have tests for check_constraint that pass so it's not easy for us to know how to replicate your issue.

Can you write some example code that shows the issue, ideally by providing a mix project that reproduces the error?

greg-rychlewski commented 1 month ago

@Artexis10 Were you able to produce a simpler example that can reproduce this? I played around with it myself and checked the code carefully and wasn't able to find a way to reproduce.

josevalim commented 4 weeks ago

Closing this. Glad to reopen if there is a way to reproduce it.