Recently I decided to try out Ecto 2.0 beta in one of my private projects. In doing so I ran into a small bug and decided to put together a simple case to reproduce the problem and then file an issue against Ecto. This post describes how I went about this process.

In my project I found that Phoenix’s mix ecto.reset command wasn’t working in that seeding the database would fail with an error like this:

** (ArgumentError) no extension found for oid `1822277` (postgrex) lib/postgrex/types.ex:298: Postgrex.Types.fetch!/2 (postgrex) lib/postgrex/types.ex:215: Postgrex.Types.encoder/2 (elixir) lib/enum.ex:1088: Enum."-map/2-lists^map/1-0-"/2 (elixir) lib/enum.ex:1088: Enum."-map/2-lists^map/1-0-"/2 (postgrex) lib/postgrex/query.ex:82: DBConnection.Query.Postgrex.Query.encoders/2 (postgrex) lib/postgrex/query.ex:43: DBConnection.Query.Postgrex.Query.describe/2 (db_connection) lib/db_connection.ex:884: DBConnection.describe_execute/5 (db_connection) lib/db_connection.ex:966: anonymous fn/4 in DBConnection.run_meter/5 (db_connection) lib/db_connection.ex:1009: DBConnection.run_begin/3 (db_connection) lib/db_connection.ex:421: DBConnection.query/4 (ecto) lib/ecto/adapters/sql.ex:380: Ecto.Adapters.SQL.struct/6 (ecto) lib/ecto/repo/schema.ex:369: Ecto.Repo.Schema.apply/5 (ecto) lib/ecto/repo/schema.ex:175: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4 (ecto) lib/ecto/repo/schema.ex:108: Ecto.Repo.Schema.insert!/4 (elixir) lib/code.ex:363: Code.require_file/2 (mix) lib/mix/tasks/run.ex:68: Mix.Tasks.Run.run/1 (mix) lib/mix/task.ex:309: Mix.Task.run_alias/3

After experimenting a bit I concluded that the problem was related to the PostGIS extension. I set about creating a new project with the minimal set of dependencies and code that can reproduce this problem.

For reference, I’m using Elixir 1.2.2 and starting out with a mix.lock file like this:

%{ " connection" : { :hex , :connection , " 1.0.2" }, " cowboy" : { :hex , :cowboy , " 1.0.4" }, " cowlib" : { :hex , :cowlib , " 1.0.2" }, " db_connection" : { :hex , :db_connection , " 0.2.4" }, " decimal" : { :hex , :decimal , " 1.1.1" }, " ecto" : { :hex , :ecto , " 1.1.4" }, " fs" : { :hex , :fs , " 0.9.2" }, " geo" : { :hex , :geo , " 1.0.1" }, " gettext" : { :hex , :gettext , " 0.10.0" }, " phoenix" : { :hex , :phoenix , " 1.1.4" }, " phoenix_ecto" : { :hex , :phoenix_ecto , " 2.0.1" }, " phoenix_html" : { :hex , :phoenix_html , " 2.5.0" }, " phoenix_live_reload" : { :hex , :phoenix_live_reload , " 1.0.3" }, " plug" : { :hex , :plug , " 1.1.2" }, " poison" : { :hex , :poison , " 1.5.2" }, " poolboy" : { :hex , :poolboy , " 1.5.1" }, " postgrex" : { :hex , :postgrex , " 0.11.1" }, " ranch" : { :hex , :ranch , " 1.2.1" }}

Then I’ll be upgrading ecto and other packages to:

index aca7970..d8d5231 100644 --- a/mix.lock +++ b/mix.lock @@ -3,15 +3,16 @@ "cowlib": {:hex, :cowlib, "1.0.2"}, "db_connection": {:hex, :db_connection, "0.2.4"}, "decimal": {:hex, :decimal, "1.1.1"}, + "ecto": {:hex, :ecto, "2.0.0-beta.1"}, "fs": {:hex, :fs, "0.9.2"}, "geo": {:hex, :geo, "1.0.1"}, "gettext": {:hex, :gettext, "0.10.0"}, "phoenix": {:hex, :phoenix, "1.1.4"}, - "phoenix_ecto": {:hex, :phoenix_ecto, "2.0.1"}, + "phoenix_ecto": {:hex, :phoenix_ecto, "3.0.0-beta.2"}, "phoenix_html": {:hex, :phoenix_html, "2.5.0"}, "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.0.3"}, "plug": {:hex, :plug, "1.1.2"}, - "poison": {:hex, :poison, "1.5.2"}, + "poison": {:hex, :poison, "2.1.0"}, "poolboy": {:hex, :poolboy, "1.5.1"}, "postgrex": {:hex, :postgrex, "0.11.1"}, "ranch": {:hex, :ranch, "1.2.1"}}

Setup the app

First, let’s create a brand new Elixir / Phoenix application:

$ mix phoenix.new oid_migration_issue * creating oid_migration_issue/config/config.exs * creating oid_migration_issue/config/dev.exs * creating oid_migration_issue/config/prod.exs * creating oid_migration_issue/config/prod.secret.exs * creating oid_migration_issue/config/test.exs * creating oid_migration_issue/lib/oid_migration_issue.ex * creating oid_migration_issue/lib/oid_migration_issue/endpoint.ex * creating oid_migration_issue/test/views/error_view_test.exs * creating oid_migration_issue/test/support/conn_case.ex * creating oid_migration_issue/test/support/channel_case.ex * creating oid_migration_issue/test/test_helper.exs * creating oid_migration_issue/web/channels/user_socket.ex * creating oid_migration_issue/web/router.ex * creating oid_migration_issue/web/views/error_view.ex * creating oid_migration_issue/web/web.ex * creating oid_migration_issue/mix.exs * creating oid_migration_issue/README.md * creating oid_migration_issue/web/gettext.ex * creating oid_migration_issue/priv/gettext/errors.pot * creating oid_migration_issue/priv/gettext/en/LC_MESSAGES/errors.po * creating oid_migration_issue/web/views/error_helpers.ex * creating oid_migration_issue/lib/oid_migration_issue/repo.ex * creating oid_migration_issue/test/support/model_case.ex * creating oid_migration_issue/priv/repo/seeds.exs * creating oid_migration_issue/.gitignore * creating oid_migration_issue/brunch-config.js * creating oid_migration_issue/package.json * creating oid_migration_issue/web/static/css/app.css * creating oid_migration_issue/web/static/js/app.js * creating oid_migration_issue/web/static/js/socket.js * creating oid_migration_issue/web/static/assets/robots.txt * creating oid_migration_issue/web/static/assets/images/phoenix.png * creating oid_migration_issue/web/static/assets/favicon.ico * creating oid_migration_issue/test/controllers/page_controller_test.exs * creating oid_migration_issue/test/views/layout_view_test.exs * creating oid_migration_issue/test/views/page_view_test.exs * creating oid_migration_issue/web/controllers/page_controller.ex * creating oid_migration_issue/web/templates/layout/app.html.eex * creating oid_migration_issue/web/templates/page/index.html.eex * creating oid_migration_issue/web/views/layout_view.ex * creating oid_migration_issue/web/views/page_view.ex Fetch and install dependencies? [Yn] * running mix deps.get * running npm install && node node_modules/brunch/bin/brunch build We are all set! Run your Phoenix application: $ cd oid_migration_issue $ mix phoenix.server You can also run your app inside IEx (Interactive Elixir) as: $ iex -S mix phoenix.server Before moving on, configure your database in config/dev.exs and run: $ mix ecto.create

I won’t follow the instructions and run mix ecto.create just yet. Instead, I’ll add Geo as a dependency.

--- a/mix.exs +++ b/mix.exs @@ -36,7 +36,9 @@ defmodule OidMigrationIssue.Mixfile do {:phoenix_html, "~> 2.4"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, {:gettext, "~> 0.9"}, - {:cowboy, "~> 1.0"}] + {:cowboy, "~> 1.0"}, + {:geo, "~> 1.0"} + ] end

$ mix deps.get Running dependency resolution Dependency resolution completed geo: 1.0.1 * Getting geo (Hex package) Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/geo-1.0.1.tar) Using locally cached package

And enable the extension for Ecto:

--- a/config/dev.exs +++ b/config/dev.exs @@ -39,4 +39,5 @@ config :oid_migration_issue, OidMigrationIssue.Repo, password: "postgres", database: "oid_migration_issue_dev", hostname: "localhost", - pool_size: 10 + pool_size: 10, + extensions: [{Geo.PostGIS.Extension, library: Geo}]

We also need to enable the PostGIS extension in the database via a migration. We’ll start by generating a new migration:

$ mix ecto.gen.migration enable_postgis * creating priv/repo/migrations * creating priv/repo/migrations/20160303080907_enable_postgis.exs

Of course, the timestamp will differ if you run this command yourself.

Next, we fill the following (taken from the Geo README) into the migration:

defmodule OidMigrationIssue . Repo . Migrations . EnablePostgis do use Ecto . Migration def up do execute " CREATE EXTENSION IF NOT EXISTS postgis" end def down do execute " DROP EXTENSION IF EXISTS postgis" end end

Let’s try it out with the ecto.setup alias. This command is a convinient alias that Phoenix creates that just runs

ecto.create to create the database

to create the database ecto.migrate to migrate the database

to migrate the database run priv/repo/seeds.exs to seed the database. $ mix ecto.setup The database for OidMigrationIssue.Repo has been created. 00:10:47.066 [info] == Running OidMigrationIssue.Repo.Migrations.EnablePostgis.up/0 forward 00:10:47.067 [info] execute “CREATE EXTENSION IF NOT EXISTS postgis” 00:10:48.611 [info] == Migrated in 15.4s

So far, so good.

Creating a PostGIS model

Now that we have Geo and PostGIS configured we need to put them to use and create a model:

$ mix phoenix.gen.model GeoModel geo_models geom:Geo.Point ** (Mix) Unknown type `Geo.Point` given to generator

Hmm, ok so we can’t use the Geo.Point type here. Instead we’ll lie and fix up the generated code later:

$ mix phoenix.gen.model GeoModel geo_models geom:string * creating priv/repo/migrations/20160303081329_create_geo_model.exs * creating web/models/geo_model.ex * creating test/models/geo_model_test.exs Remember to update your repository by running migrations: $ mix ecto.migrate

Then we’ll switch over to using Geo.Point and :geometry :

diff --git a/priv/repo/migrations/20160303081329_create_geo_model.exs b/priv/repo/migrations/20160303081329_create_geo_model.exs index 62db09b..abc0c55 100644 --- a/priv/repo/migrations/20160303081329_create_geo_model.exs +++ b/priv/repo/migrations/20160303081329_create_geo_model.exs @@ -3,7 +3,7 @@ defmodule OidMigrationIssue.Repo.Migrations.CreateGeoModel do def change do create table(:geo_models) do - add :geom, :string + add :geom, :geometry timestamps end diff --git a/test/models/geo_model_test.exs b/test/models/geo_model_test.exs index d6f380b..29cb661 100644 --- a/test/models/geo_model_test.exs +++ b/test/models/geo_model_test.exs @@ -3,7 +3,7 @@ defmodule OidMigrationIssue.GeoModelTest do alias OidMigrationIssue.GeoModel - @valid_attrs %{geom: "some content"} + @valid_attrs %{geom: %Geo.Point{coordinates: {30, -90}, srid: 4326}} @invalid_attrs %{} test "changeset with valid attributes" do diff --git a/web/models/geo_model.ex b/web/models/geo_model.ex index f0eeeff..46dfe49 100644 --- a/web/models/geo_model.ex +++ b/web/models/geo_model.ex @@ -2,7 +2,7 @@ defmodule OidMigrationIssue.GeoModel do use OidMigrationIssue.Web, :model schema "geo_models" do - field :geom, :string + field :geom, Geo.Point timestamps end

Adding Seeds

Let’s just write a simple seeds script to seed a point into our database. Here’s my seeds.exs script:

alias OidMigrationIssue . { Repo , GeoModel } % GeoModel {} |> GeoModel . changeset (%{ geom: % Geo . Point { coordinates: { 30 , - 90 }, srid: 4326 }}) |> Repo . insert!

Then, we can use ecto.reset to reset our database using the new seeds:

$ mix ecto.reset The database for OidMigrationIssue.Repo has been dropped. The database for OidMigrationIssue.Repo has been created. 00:21:44.809 [info] == Running OidMigrationIssue.Repo.Migrations.EnablePostgis.up/0 forward 00:21:44.811 [info] execute "CREATE EXTENSION IF NOT EXISTS postgis" 00:21:45.941 [info] == Migrated in 11.2s 00:21:45.996 [info] == Running OidMigrationIssue.Repo.Migrations.CreateGeoModel.change/0 forward 00:21:45.996 [info] create table geo_models 00:21:46.006 [info] == Migrated in 0.1s [debug] INSERT INTO "geo_models" ("inserted_at", "updated_at", "geom") VALUES ($1, $2, $3) RETURNING "id" [{ {2016, 3, 3}, {8, 21, 46, 0} }, { {2016, 3, 3}, {8, 21, 46, 0} }, %Geo.Point{coordinates: {30, -90}, srid: 4326}] OK query=43.3ms

Good, everything seems to be working fine.

Updating to Ecto 2.0 beta

The next step is to upgrade to Ecto 2.0 beta. We’ll follow the instructions from http://blog.plataformatec.com.br/2016/02/ecto-2-0-0-beta-0-is-out/. Fortunately, we don’t have that much to do since we’ve written so little code.

diff --git a/mix.exs b/mix.exs index 58cda12..f2a3e9e 100644 --- a/mix.exs +++ b/mix.exs @@ -32,7 +32,7 @@ defmodule OidMigrationIssue.Mixfile do defp deps do [{:phoenix, "~> 1.1.4"}, {:postgrex, ">= 0.0.0"}, - {:phoenix_ecto, "~> 2.0"}, + {:phoenix_ecto, "~> 3.0.0-beta"}, {:phoenix_html, "~> 2.4"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, {:gettext, "~> 0.9"}, diff --git a/test/support/channel_case.ex b/test/support/channel_case.ex index ca65c92..bd242ec 100644 --- a/test/support/channel_case.ex +++ b/test/support/channel_case.ex @@ -32,10 +32,7 @@ defmodule OidMigrationIssue.ChannelCase do end setup tags do - unless tags[:async] do - Ecto.Adapters.SQL.restart_test_transaction(OidMigrationIssue.Repo, []) - end - + :ok = Ecto.Adapters.SQL.Sandbox.checkout(Demo.Repo) :ok end end diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 8affedf..67dd527 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -33,10 +33,7 @@ defmodule OidMigrationIssue.ConnCase do end setup tags do - unless tags[:async] do - Ecto.Adapters.SQL.restart_test_transaction(OidMigrationIssue.Repo, []) - end - + :ok = Ecto.Adapters.SQL.Sandbox.checkout(Demo.Repo) {:ok, conn: Phoenix.ConnTest.conn()} end end diff --git a/test/support/model_case.ex b/test/support/model_case.ex index c3b0e07..6db2da6 100644 --- a/test/support/model_case.ex +++ b/test/support/model_case.ex @@ -26,10 +26,7 @@ defmodule OidMigrationIssue.ModelCase do end setup tags do - unless tags[:async] do - Ecto.Adapters.SQL.restart_test_transaction(OidMigrationIssue.Repo, []) - end - + :ok = Ecto.Adapters.SQL.Sandbox.checkout(Demo.Repo) :ok end diff --git a/test/test_helper.exs b/test/test_helper.exs index 973f1a8..6892146 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -2,5 +2,4 @@ ExUnit.start Mix.Task.run "ecto.create", ~w(-r OidMigrationIssue.Repo --quiet) Mix.Task.run "ecto.migrate", ~w(-r OidMigrationIssue.Repo --quiet) -Ecto.Adapters.SQL.begin_test_transaction(OidMigrationIssue.Repo) - +Ecto.Adapters.SQL.Sandbox.mode(OidMigrationIssue.Repo, :manual)

Now, to install the deps:

$ mix deps.get Running dependency resolution Conflict on ecto mix.lock: 1.1.4 phoenix_ecto from 3.0.0-beta.0 to 3.0.0-beta.2: ~> 2.0-beta ** (Mix) Hex dependency resolution failed, relax the version requirements or unlock dependencies

We need to follow the instructions here and unlock ecto:

$ mix deps.unlock ecto $ mix deps.get Running dependency resolution Conflict on ecto 2.0.0-beta.0, 2.0.0-beta.1 geo 1.0.1: ~> 1.1 phoenix_ecto from 3.0.0-beta.0 to 3.0.0-beta.2: ~> 2.0-beta ** (Mix) Hex dependency resolution failed, relax the version requirements or unlock dependencies

Ah, so Geo says it depends on Ecto 1.1. I’ve tested this before and I think Geo can work fine with Ecto 2.0 so let’s override it:

diff --git a/mix.exs b/mix.exs index f2a3e9e..1772008 100644 --- a/mix.exs +++ b/mix.exs @@ -35,6 +35,7 @@ defmodule OidMigrationIssue.Mixfile do {:phoenix_ecto, "~> 3.0.0-beta"}, {:phoenix_html, "~> 2.4"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, + {:ecto, "~> 2.0-beta", override: true}, {:gettext, "~> 0.9"}, {:cowboy, "~> 1.0"}, {:geo, "~> 1.0"}

And now we can install the deps we want:

$ mix deps.unlock --all $ mix deps.get Running dependency resolution Dependency resolution completed connection: 1.0.2 cowboy: 1.0.4 cowlib: 1.0.2 db_connection: 0.2.4 decimal: 1.1.1 ecto: 2.0.0-beta.1 fs: 0.9.2 geo: 1.0.1 gettext: 0.10.0 phoenix: 1.1.4 phoenix_ecto: 3.0.0-beta.2 phoenix_html: 2.5.0 phoenix_live_reload: 1.0.3 plug: 1.1.2 poison: 2.1.0 poolboy: 1.5.1 postgrex: 0.11.1 ranch: 1.2.1 * Updating poison (Hex package) Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/poison-2.1.0.tar) Using locally cached package

Ecto reset

Now, let’s retry our ecto.reset command again:

$ mix ecto.reset The database for OidMigrationIssue.Repo has been dropped. The database for OidMigrationIssue.Repo has been created. 00:34:57.457 [info] == Running OidMigrationIssue.Repo.Migrations.EnablePostgis.up/0 forward 00:34:57.459 [info] execute "CREATE EXTENSION IF NOT EXISTS postgis" 00:34:58.653 [info] == Migrated in 11.9s 00:34:58.710 [info] == Running OidMigrationIssue.Repo.Migrations.CreateGeoModel.change/0 forward 00:34:58.710 [info] create table geo_models 00:34:58.715 [info] == Migrated in 0.0s ** (ArgumentError) no extension found for oid `1822277` (postgrex) lib/postgrex/types.ex:298: Postgrex.Types.fetch!/2 (postgrex) lib/postgrex/types.ex:215: Postgrex.Types.encoder/2 (elixir) lib/enum.ex:1088: Enum."-map/2-lists^map/1-0-"/2 (elixir) lib/enum.ex:1088: Enum."-map/2-lists^map/1-0-"/2 (postgrex) lib/postgrex/query.ex:82: DBConnection.Query.Postgrex.Query.encoders/2 (postgrex) lib/postgrex/query.ex:43: DBConnection.Query.Postgrex.Query.describe/2 (db_connection) lib/db_connection.ex:884: DBConnection.describe_execute/5 (db_connection) lib/db_connection.ex:966: anonymous fn/4 in DBConnection.run_meter/5 (db_connection) lib/db_connection.ex:1009: DBConnection.run_begin/3 (db_connection) lib/db_connection.ex:421: DBConnection.query/4 (ecto) lib/ecto/adapters/sql.ex:380: Ecto.Adapters.SQL.struct/6 (ecto) lib/ecto/repo/schema.ex:369: Ecto.Repo.Schema.apply/5 (ecto) lib/ecto/repo/schema.ex:175: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4 (ecto) lib/ecto/repo/schema.ex:108: Ecto.Repo.Schema.insert!/4 (elixir) lib/code.ex:363: Code.require_file/2 (mix) lib/mix/tasks/run.ex:68: Mix.Tasks.Run.run/1 (mix) lib/mix/task.ex:309: Mix.Task.run_alias/3

Ok, good. This is the failure we expected. Our reproduction case is doing its job. Let’s confirm it’s behaving the way I claim it is.

Note that if I remove the seed command from the aliases like this:

diff --git a/mix.exs b/mix.exs index 1772008..ccd92b7 100644 --- a/mix.exs +++ b/mix.exs @@ -49,7 +49,7 @@ defmodule OidMigrationIssue.Mixfile do # # See the documentation for `Mix` for more info on aliases. defp aliases do - ["ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], + ["ecto.setup": ["ecto.create", "ecto.migrate"], "ecto.reset": ["ecto.drop", "ecto.setup"]] end end

and then run reset and seed as two commands then everything works as it should:

$ mix ecto.reset && mix run priv/repo/seeds.exs The database for OidMigrationIssue.Repo has been dropped. The database for OidMigrationIssue.Repo has been created. 09:10:52.465 [info] == Running OidMigrationIssue.Repo.Migrations.EnablePostgis.up/0 forward 09:10:52.467 [info] execute "CREATE EXTENSION IF NOT EXISTS postgis" 09:10:53.649 [info] == Migrated in 11.8s 09:10:53.702 [info] == Running OidMigrationIssue.Repo.Migrations.CreateGeoModel.change/0 forward 09:10:53.702 [info] create table geo_models 09:10:53.707 [info] == Migrated in 0.0s [debug] INSERT INTO "geo_models" ("inserted_at","updated_at","geom") VALUES ($1,$2,$3) RETURNING "id" [{ {2016, 3, 3}, {17, 10, 54, 0} }, { {2016, 3, 3}, {17, 10, 54, 0} }, %Geo.Point{coordinates: {30, -90}, srid: 4326}] OK query=6.7ms queue=48.7ms

So this appears to be a problem running the commands within a single mix invocation.

Look over the existing issues

Before I go ahead and file an issue against Ecto I should check to see if there is one already filed. Searching, I see Reload TYPE ENUM (Postgre) before migration which has been fixed. But, reading through the issue, it sounds like it describes a very similar issue that would come up when migrating a database due to the Postgres types cache. I wonder if our issue is due to the same root cause? That is, the problem has been fixed for migrations but the problem affects seeds as well.

I can try adding some code to my seeds based on the fix for the above issue. Based on my reading of the fixes I need to add:

diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 13152f0..dd2b82b 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -12,6 +12,9 @@ alias OidMigrationIssue.{Repo, GeoModel} +{:ok, _} = Application.ensure_all_started(:ecto) +{:ok, _} = Application.ensure_all_started(:postgrex) + %GeoModel{} |> GeoModel.changeset(%{geom: %Geo.Point{coordinates: {30, -90}, srid: 4326}}) |> Repo.insert!

But running this version I still get the same error.

Try out Ecto master

We should try out the master branch of Ecto to see if the issue has been fixed there but not yet published in a release. To do this we make this change to mix.exs:

diff --git a/mix.exs b/mix.exs index 1772008..5c0827b 100644 --- a/mix.exs +++ b/mix.exs @@ -35,7 +35,7 @@ defmodule OidMigrationIssue.Mixfile do {:phoenix_ecto, "~> 3.0.0-beta"}, {:phoenix_html, "~> 2.4"}, {:phoenix_live_reload, "~> 1.0", only: :dev}, - {:ecto, "~> 2.0-beta", override: true}, + {:ecto, github: "elixir-lang/ecto", branch: "master", override: true}, {:gettext, "~> 0.9"}, {:cowboy, "~> 1.0"}, {:geo, "~> 1.0"}

Then update the deps

$ mix deps.get * Getting ecto (https://github.com/elixir-lang/ecto.git) Cloning into '/Users/jkain/Documents/Projects/elixir/oid_migration_issue/deps/ecto'... remote: Counting objects: 25829, done. remote: Compressing objects: 100% (232/232), done. remote: Total 25829 (delta 110), reused 2 (delta 2), pack-reused 25594 Receiving objects: 100% (25829/25829), 6.58 MiB | 2.59 MiB/s, done. Resolving deltas: 100% (14906/14906), done. Checking connectivity... done. Running dependency resolution

I see the same problem:

$ mix ecto.reset The database for OidMigrationIssue.Repo has been dropped. The database for OidMigrationIssue.Repo has been created. 09:20:59.536 [info] == Running OidMigrationIssue.Repo.Migrations.EnablePostgis.up/0 forward 09:20:59.537 [info] execute "CREATE EXTENSION IF NOT EXISTS postgis" 09:21:00.774 [info] == Migrated in 12.3s 09:21:00.817 [info] == Running OidMigrationIssue.Repo.Migrations.CreateGeoModel.change/0 forward 09:21:00.817 [info] create table geo_models 09:21:00.822 [info] == Migrated in 0.0s ** (ArgumentError) no extension found for oid `1841936` (postgrex) lib/postgrex/types.ex:298: Postgrex.Types.fetch!/2 (postgrex) lib/postgrex/types.ex:215: Postgrex.Types.encoder/2 (elixir) lib/enum.ex:1088: Enum."-map/2-lists^map/1-0-"/2 (elixir) lib/enum.ex:1088: Enum."-map/2-lists^map/1-0-"/2 (postgrex) lib/postgrex/query.ex:82: DBConnection.Query.Postgrex.Query.encoders/2 (postgrex) lib/postgrex/query.ex:43: DBConnection.Query.Postgrex.Query.describe/2 (db_connection) lib/db_connection.ex:884: DBConnection.describe_execute/5 (db_connection) lib/db_connection.ex:966: anonymous fn/4 in DBConnection.run_meter/5 (db_connection) lib/db_connection.ex:1009: DBConnection.run_begin/3 (db_connection) lib/db_connection.ex:421: DBConnection.query/4 (ecto) lib/ecto/adapters/sql.ex:387: Ecto.Adapters.SQL.struct/6 (ecto) lib/ecto/repo/schema.ex:369: Ecto.Repo.Schema.apply/5 (ecto) lib/ecto/repo/schema.ex:175: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4 (ecto) lib/ecto/repo/schema.ex:108: Ecto.Repo.Schema.insert!/4 (elixir) lib/code.ex:363: Code.require_file/2 (mix) lib/mix/tasks/run.ex:68: Mix.Tasks.Run.run/1 (mix) lib/mix/task.ex:309: Mix.Task.run_alias/3

File an Issue and See it Fixed

I filed a new issue and filled in the template and a link to the repo for this simple reproducer.

The issue was fixed in under an hour and half. Here’s the commit.

The fix is in master, let’s try it out. We already have the change to fetch Ecto from master. I just need to unlock Ecto and update to the newest master. Then

$ mix ecto.reset The database for OidMigrationIssue.Repo has been dropped. The database for OidMigrationIssue.Repo has been created. 07:37:25.415 [info] == Running OidMigrationIssue.Repo.Migrations.EnablePostgis.up/0 forward 07:37:25.417 [info] execute "CREATE EXTENSION IF NOT EXISTS postgis" 07:37:26.941 [info] == Migrated in 15.2s 07:37:26.994 [info] == Running OidMigrationIssue.Repo.Migrations.CreateGeoModel.change/0 forward 07:37:26.994 [info] create table geo_models 07:37:26.999 [info] == Migrated in 0.0s [debug] INSERT INTO "geo_models" ("inserted_at","updated_at","geom") VALUES ($1,$2,$3) RETURNING "id" [{ {2016, 3, 5}, {15, 37, 27, 0} }, { {2016, 3, 5}, {15, 37, 27, 0} }, %Geo.Point{coordinates: {30, -90}, srid: 4326}] OK query=7.0ms queue=27.3ms

It works! Thanks José and Ecto team!

Conclusion

I hope you enjoyed this post on my experiences with Ecto 2.0-beta and building a simple reproduction case. I know it was a good oppourtunity for me to help out with the testing of Ecto 2.0.