Changing primary key requires references to have :type defined

359 views
Skip to first unread message

Aeliton Silva

unread,
Sep 3, 2017, 11:27:51 PM9/3/17
to elixir-ecto
Hello All,

I'm changing all the primary keys to an custom generated using:

config :app, App.Repo, migration_primary_key: [id: :uuid, type: :binary_id]

As defined at the docs.

After doing that, all my references got:
** (Postgrex.Error) ERROR 42804 (datatype_mismatch): foreign key constraint "exams_referring_physician_id_fkey" cannot be implemented

Key columns "referring_physician_id" and "id" are of incompatible types: bigint and character varying.

My expectations were that once I tell ecto that I'll use type :string as default primary key type, all the foreign keys would have the same type as well. Does that make sense?

The solution seems to be pretty simple:

diff --git a/lib/ecto/migration.ex b/lib/ecto/migration.ex
index 3ee02688..58b1b355 100644
--- a/lib/ecto/migration.ex
+++ b/lib/ecto/migration.ex
@@ -834,6 +834,7 @@ defmodule Ecto.Migration do
   end

   def references(table, opts) when is_binary(table) and is_list(opts) do
+    opts = opts ++ Runner.repo_config(:migration_primary_key, [])
     reference = struct(%Reference{table: table}, opts)

     unless reference.on_delete in [:nothing, :delete_all, :nilify_all] do
diff --git a/test/ecto/migration_test.exs b/test/ecto/migration_test.exs
index 1c54d60e..c7d169c6 100644
--- a/test/ecto/migration_test.exs
+++ b/test/ecto/migration_test.exs
@@ -514,5 +514,16 @@ defmodule Ecto.MigrationTest do
     assert "SELECT 2" = last_command()
   end

+  test "references foreing keys types must be the same as primary defaults" do
+    %{runner: runner} = Process.get(:ecto_migration)
+    Agent.update(runner, fn state ->
+      config = Keyword.put(state.config, :migration_primary_key, [type: :binary_id])
+      Map.put(state, :config, config)
+    end)
+
+    assert references(:posts) ==
+           %Reference{table: "posts", column: :id, type: :binary_id}
+  end
+
   defp last_command(), do: Process.get(:last_command)
 end

 
What do you guys think?

Kind regards,
Aeliton

José Valim

unread,
Sep 4, 2017, 2:46:25 AM9/4/17
to elixi...@googlegroups.com
Yes, great catch! Please send a PR.
--


José Valim
Skype: jv.ptec
Founder and Director of R&D

Aeliton Germano

unread,
Sep 4, 2017, 11:50:46 AM9/4/17
to elixi...@googlegroups.com
The PR is created José Valim. Thanks.

--
You received this message because you are subscribed to the Google Groups "elixir-ecto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-ecto+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-ecto/CAGnRm4LSaDZx1OneTXEKvxp5%2BoEJwUmGET5V3RXdNHZUZ%3DJo4g%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.



--
Aeliton G. da Silva
Reply all
Reply to author
Forward
0 new messages