thiagomajesk

thiagomajesk

Ecto schemaless insert_all throwing error on data type missmatch

Hi! Just stumbled upon this error today and I’m not sure I understand why this is happening - besides, of course, the obvious problem Postgrex is reporting:

Postgrex expected a binary of 16 bytes, got “4c67a49e-fd03-4c1a-9679-713e952ecf73”. Please make sure the value you are passing matches the definition in your table or in your query or convert the value accordingly.

I’m trying to insert a row in a table that has the correct type and is properly migrated:

INSERT INTO "organization_members" ("organization_id","role","user_id") VALUES ($1,$2,$3) [1, "admin", "4c67a49e-fd03-4c1a-9679-713e952ecf73"]

And the migration is:

create table(:organizations_members, primary_key: false) do
  add :organization_id, references(:organizations), primary_key: true
  add :user_id, references(:users, type: :uuid), primary_key: true
  add :role, OrganizationMemberRole.type(), default: "reader"
end

create index(:organizations_members, [:organization_id, :user_id])

And I’m inserting it like this:

insert_membership = fn repo, %{organization: organization} ->
  membership = %{user_id: user.id, organization_id: organization.id, role: "admin"}
  repo.insert_all("organizations_members", [membership])
end

Ecto.Multi.new()
|> Ecto.Multi.insert(:organization, Organization.changeset(%Organization{}, attrs))
|> Ecto.Multi.run(:members, insert_membership)
|> Repo.transaction()
|> case do
  {:ok, %{organization: organization}} -> {:ok, organization}
  {:error, :organization_id, changeset, _} -> {:error, changeset}
  {:error, :members, _, _} -> :error
end

Interestingly enough, if I insert it by hand I don’t have a problem at all, so I guess something is happening when Postgrex is trying to return the query results. Also, the console outputs:

[debug] Query OK db=0.7ms`
rollback []

I think I’ve read somewhere that it would be possible to specify the data types for schemaless operations (or changesets) I don’t remember exactly. So, if someone has a fresh memory on the subject I’d really appreciate the help.

Marked As Solved

cenotaph

cenotaph

Ah checked your post on mobile first and missed the important part.

When you retrieved your user through Ecto it did it’s casting and all the magic.

Your user.id is a string and not a binary (for postgres) since you are entering data without ecto casting in the insert_all method it generates that error. The following should help you.

insert_membership = fn repo, %{organization: organization} ->
  membership = %{user_id: Ecto.UUID.dump!(user.id), organization_id: organization.id, role: "admin"}
  repo.insert_all("organizations_members", [membership])
end

https://hexdocs.pm/ecto/Ecto.UUID.html#dump!/1

Converts a string representing a UUID into a binary.

Also Liked

thiagomajesk

thiagomajesk

Yep, this seems about right… I always forget that if you’re not using a changeset to sanitize data you’re basically on your own with Ecto. What caught me by surprise though is that Postgrex wouldn’t just dump it or pass the input down directly to Postgres.

Thanks for the help @cenotaph. Cheers!

Where Next?

Popular in Questions Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
New
logicmason
Hi there, I'm working through my first release with elixir/phoenix. I've built a release with distillery and found that it crashes when I...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New

Other popular topics Top

William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement