cboebel

cboebel

Hello,

I’m having a vexing issue using Ecto.UUIDs as my primary key in a table. When I create a record, I generate the UUID for the id, and pass that along with the other fields to insert. A record is created, and the UUID is shown. When I query the record, I get a different UUID back.

Here’s an example of what I’m seeing. Code for the schema and repo follow the example.

I believe I’m doing something dumb but, at least for me, the dumber it is the harder it is to find.

iex(5)> Repo.insert(%ReplicationType{id: Ecto.UUID.generate(), name: "test3"})
18:32:49.063 [debug] QUERY OK db=0.8ms queue=7.6ms
INSERT INTO `replication_types` (`id`,`name`,`inserted_at`,`updated_at`) VALUES (?,?,?,?) [<<71, 34, 96, 242, 205, 97, 72, 47, 171, 47, 132, 161, 18, 187, 187, 138>>, "test3", ~N[2019-04-19 22:32:49], ~N[2019-04-19 22:32:49]]
{:ok,
 %Pserver.Pserver.ReplicationType{
   __meta__: #Ecto.Schema.Metadata<:loaded, "replication_types">,
   id: "472260f2-cd61-482f-ab2f-84a112bbbb8a",
   inserted_at: ~N[2019-04-19 22:32:49],
   name: "test3",
   replication_tables: #Ecto.Association.NotLoaded<association :replication_tables is not loaded>,
   sites: #Ecto.Association.NotLoaded<association :sites is not loaded>,
   updated_at: ~N[2019-04-19 22:32:49]
 }}
iex(6)> Repo.get_by(ReplicationType, name: "test3")                           
18:33:11.506 [debug] QUERY OK source="replication_types" db=8.9ms
SELECT r0.`id`, r0.`name`, r0.`inserted_at`, r0.`updated_at` FROM `replication_types` AS r0 WHERE (r0.`name` = ?) ["test3"]
%Pserver.Pserver.ReplicationType{
  __meta__: #Ecto.Schema.Metadata<:loaded, "replication_types">,
  id: "4722603f-3f61-482f-3f2f-3f3f123f3f3f",
  inserted_at: ~N[2019-04-19 22:32:49],
  name: "test3",
  replication_tables: #Ecto.Association.NotLoaded<association :replication_tables is not loaded>,
  sites: #Ecto.Association.NotLoaded<association :sites is not loaded>,
  updated_at: ~N[2019-04-19 22:32:49]
}

the code for ReplicationType:

defmodule Pserver.Pserver.ReplicationType do
  use Ecto.Schema
  import Ecto.Changeset
  alias Pserver.Pserver.{ReplicationTable, Site}

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id
  schema "replication_types" do
    # field :id, :binary_id
    field :name, :string
    
    has_many :sites, Site
    has_many :replication_tables, ReplicationTable
    timestamps()
  end

  @doc false
  def changeset(replication_type, attrs) do
    replication_type
    |> cast(attrs, [:name])
    |> validate_required([:name])
    |> unique_constraint(:name)
  end
end

And the Repo…

defmodule Pserver.Repo do
  use Ecto.Repo,
    otp_app: :pserver,
    adapter: Ecto.Adapters.MySQL
end

Thank you!

Showing Posts 1 to 10

al2o3cr

al2o3cr

This won’t let id through, causing the built-in autogenerate to run instead.

axelson

axelson

Scenic Core Team

I don’t think that’s it since he’s passing the id as part of the struct itself %ReplicationType{id: Ecto.UUID.generate(), name: "test3"} (and he’s not going through the changeset at all)

@cboebel what version of mysql are you using and what is the exact column type of the id? Also you might want to checkout the MyXQL adapter: GitHub - elixir-ecto/myxql: MySQL 5.5+ driver for Elixir · GitHub (I don’t see any UUID support mentioned but I would it expect it to work with direct binaries)

cboebel

cboebel OP

This is correct. The example I posted doesn’t use the changeset.

I’m using 5.7.25 MySQL Community Server (GPL).

The column type is binary(16)

cboebel

cboebel OP

I should also point out that this happens if I generate the UUID myself or let it happen as part of the autogenerate.

axelson

axelson

Scenic Core Team

What column type in MySQL are you using?

cboebel

cboebel OP

binary(16)

cboebel

cboebel OP

Also tried this we MySQL 8 - same results.

simon

simon

I discovered this in the context of migrations so it might not make any difference here but when your define your primary key add read_after_writes: true.

@primary_key {:id, :binary_id, autogenerate: true, read_after_writes: true}

cboebel

cboebel OP

MySQL does not like this:

For relational databases, this means the RETURNING option of those statements is used. For this reason, MySQL does not support this option and will raise an error if a schema is inserted/updated with read after writes fields.

isaac-rstor

isaac-rstor

Can you double check that your character encoding and collation is ok? Ecto’s MySQL doesn’t support certain of MySQL encoding types, and I remember having major problems with uuids that drove me up the wall (but were solvable - except when I had to interface with other databases at work) until I switched to postgres.

I can’t be 100% sure but I recall values being trimmed at 3f as being diagnostic of the problem – you’ll have to use utf8- something other other and not Latin, which is the default in MySQL iirc.

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
matt-savvy
Anyone here using Honeybadger? My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of Bandit.HTTPError...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews