Ecto update tests failing due to :utc_datetime_usec

I recently upgraded a project from Ecto 2~ to Ecto 3. I was able to get all tests passing locally, there were a few instances were tests were failing due to microsecond precision so I added @trimestamps_opts [type: :utc_datetime_usec] and everything worked.

However, when I run tests in Docker (via Bitbucket pipelines) I get this error:

  1) test list/0 returns all vendors .../vendors/vendors_test.exs:36
     Assertion with == failed
     code:  assert expected == [actual]
     left:  [
              %Vendor{
                __meta__: #Ecto.Schema.Metadata<:loaded, "vendors">,
                cut_off_time: ~T[12:00:00],
                email: nil,
                holidays: [],
                id: 3,
                inserted_at: ~N[2022-11-10 00:30:35.000000],
                key: "Vendor 3",
                lead_time: 2,
                name: "Vendor 11",
                timezone: "US/Eastern",
                updated_at: ~N[2022-11-10 00:30:35.000000]
              }
            ]
     right: [
              %Vendor{
                __meta__: #Ecto.Schema.Metadata<:loaded, "vendors">,
                cut_off_time: ~T[12:00:00],
                email: nil,
                holidays: [],
                id: 3,
                inserted_at: ~N[2022-11-10 00:30:34.544646],
                key: "Vendor 3",
                lead_time: 2,
                name: "Vendor 11",
                timezone: "US/Eastern",
                updated_at: ~N[2022-11-10 00:30:34.544646]
              }
            ]
     stacktrace:
       ...vendors/vendors_test.exs:39: (test)

This is the particular test in question:

  test "list/0 returns all vendors" do
    actual = insert(:vendor)
    expected = Vendors.list()
    assert expected == [actual]
  end

To me, this looks as if ExMachina is creating a vendor with a datetime utc_datetime_usec that respects microseconds, but it is not being persisted into the database as such? Again, this test gives me no trouble locally it’s only when the test runs via Docker while deploying.

You’d want to make sure to change your migrations to _usec types as well. Postgres allows setting a precision on timestamp columns and ecto started to use that at some point.

1 Like

Thanks, I was hoping to be migration free but I think this is only really an issue for one model so not a big deal!

This is all working locally and build pipelines are passing however when attempting to deploy to AWS with codedeploy the build fails and I get this error:

[2022-11-24 13:12:40.461] [d-21Y4AQLHK][stdout]alter table products
[2022-11-24 13:12:40.476] [d-21Y4AQLHK][stderr]** (Postgrex.Error) ERROR 42704 (undefined_object): type "utc_datetime_usec" does not exist
[2022-11-24 13:12:40.476] [d-21Y4AQLHK][stderr]    (ecto 2.2.12) lib/ecto/adapters/sql.ex:200: Ecto.Adapters.SQL.query!/5
[2022-11-24 13:12:40.476] [d-21Y4AQLHK][stderr]    (ecto 2.2.12) lib/ecto/adapters/postgres.ex:96: anonymous fn/4 in Ecto.Adapters.Postgres.execute_ddl/3
[2022-11-24 13:12:40.476] [d-21Y4AQLHK][stderr]    (elixir 1.13.4) lib/enum.ex:2396: Enum."-reduce/3-lists^foldl/2-0-"/3
[2022-11-24 13:12:40.476] [d-21Y4AQLHK][stderr]    (ecto 2.2.12) lib/ecto/adapters/postgres.ex:96: Ecto.Adapters.Postgres.execute_ddl/3
[2022-11-24 13:12:40.476] [d-21Y4AQLHK][stderr]    (ecto 2.2.12) lib/ecto/migration/runner.ex:104: anonymous fn/2 in Ecto.Migration.Runner.flush/0
[2022-11-24 13:12:40.476] [d-21Y4AQLHK][stderr]    (elixir 1.13.4) lib/enum.ex:2396: Enum."-reduce/3-lists^foldl/2-0-"/3
[2022-11-24 13:12:40.476] [d-21Y4AQLHK][stderr]    (ecto 2.2.12) lib/ecto/migration/runner.ex:102: Ecto.Migration.Runner.flush/0
[2022-11-24 13:12:40.476] [d-21Y4AQLHK][stderr]    (stdlib 4.0.1) timer.erl:250: :timer.tc/2