gpt4 book ai didi

elixir - 类型不匹配插入 :binary_id with Ecto changeset

转载 作者:行者123 更新时间:2023-12-03 09:53:11 33 4
gpt4 key购买 nike

我有一张 table applications带外键 user_id那是一个 Postgres uuid .我在我的 web.ex :

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

我的模型是:
defmodule Dashboard.Application do
use Dashboard.Web, :model

alias Dashboard.User
alias Dashboard.Path

schema "applications" do
field :name, :string
belongs_to :user, User
has_many :paths, Path
timestamps
end

@required_fields ~w(name user_id)
@optional_fields ~w()

def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
end

但是,当我尝试使用来自 users 的有效 uuid 使用变更集进行插入时表,我得到
[error] #PID<0.407.0> running Dashboard.Endpoint terminated
Server: localhost:4000 (http)
Request: POST /applications
** (exit) an exception was raised:
** (Ecto.ChangeError) value `<<184, 235, 134, 244, 95, 86, 74, 133, 159, 153, 31, 111, 16, 28, 76, 15>>` for `Dashboard.Application.user_id` in `insert` does not match type :binary_id
(ecto) lib/ecto/query/planner.ex:33: anonymous fn/6 in Ecto.Query.Planner.fields/4
(stdlib) lists.erl:1262: :lists.foldl/3
(ecto) lib/ecto/query/planner.ex:21: Ecto.Query.Planner.fields/4
(ecto) lib/ecto/repo/schema.ex:449: Ecto.Repo.Schema.dump_changes/5
(ecto) lib/ecto/repo/schema.ex:77: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4
(ecto) lib/ecto/repo/schema.ex:477: anonymous fn/3 in Ecto.Repo.Schema.wrap_in_transaction/9
(ecto) lib/ecto/pool.ex:292: Ecto.Pool.with_rollback/3
(ecto) lib/ecto/adapters/sql.ex:582: Ecto.Adapters.SQL.transaction/8
(ecto) lib/ecto/pool.ex:244: Ecto.Pool.outer_transaction/6
(ecto) lib/ecto/adapters/sql.ex:551: Ecto.Adapters.SQL.transaction/3
(dashboard) web/controllers/application_controller.ex:16: Dashboard.ApplicationController.create/2

检查 user_id我懂了:
pry(1)> params["user_id"] |> i
Term
<<184, 235, 134, 244, 95, 86, 74, 133, 159, 153, 31, 111, 16, 28, 76, 15>>
Data type
BitString
Byte size
16
Description
This is a binary: a collection of bytes. It's printed with the `<<>>`
syntax (as opposed to double quotes) because it is not a
UTF-8 encoded binary (the first invalid byte being `<<184>>`)
Reference modules
:binary

这看起来像是试图向我插入一个有效的 16 字节 uuid。我错过了什么?谢谢!

更新:这是数据库架构:
              Table "public.applications"
Column | Type | Modifiers
-------------+-----------------------------+-----------
id | uuid | not null
user_id | uuid | not null
name | text | not null
inserted_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
Indexes:
"applications_pkey" PRIMARY KEY, btree (id)
"applications_user_id_index" btree (user_id)
Foreign-key constraints:
"applications_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
Referenced by:
TABLE "paths" CONSTRAINT "paths_application_id_fkey" FOREIGN KEY (application_id) REFERENCES applications(id) ON DELETE CASCADE

Table "public.users"
Column | Type | Modifiers
-------------+-----------------------------+-----------
id | uuid | not null
email | text | not null
inserted_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
avatar | text | not null
name | text | not null
data | jsonb | not null
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"users_email_index" UNIQUE, btree (email)
Referenced by:
TABLE "applications" CONSTRAINT "applications_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE

更新 2:
我已经升级到 phoenix 1.2 和 ecto 2.0.2 问题依旧

更新 3:
我认为这可能是 Ecto 中的一个错误。我已经尽力修复了一个 PR: https://github.com/elixir-ecto/ecto/pull/1585

最佳答案

使用 binary_id 的 Ecto 模式期望数据是字符串格式的 UUID,然后由 Ecto 自动转换为 16 字节的二进制格式。

如果你想直接使用二进制表示,你可以将类型定义为 :binary_id

schema "applications" do
field :name, :string
belongs_to :user, User, foreign_key: :user_id, type: :binary_id
has_many :paths, Path
timestamps
end

或者使用 Ecto.UUID.load 将二进制数据转换为字符串:
iex(38)> binary = Ecto.UUID.bingenerate()
<<91, 154, 58, 233, 38, 235, 76, 200, 188, 162, 112, 23, 233, 223, 191, 144>>
iex(39)> Ecto.UUID.load(binary)
{:ok, "5b9a3ae9-26eb-4cc8-bca2-7017e9dfbf90"}

关于elixir - 类型不匹配插入 :binary_id with Ecto changeset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38427551/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com