【发布时间】:2023-03-20 10:49:01
【问题描述】:
我正在使用 Ecto (2.2.8) 来处理现有的 PostgreSQL 数据库。
我定义了两个模式来表示owner 和house。 house 架构有一个 FK (belongs_to) owner。我为house 定义了一个架构和一个变更集,如下所示:
@primary_key {:id, :id, autogenerate: true}
schema "house" do
belongs_to :owner, Owner, foreign_key: :owner_id
field :name, :string
end
def changeset(house, params \\ %{}) do
house
|> cast(params, [:name, :owner_id])
|> validate_required([:owner_id])
|> foreign_key_constraint(:owner_id)
end
问题
当数据库中没有带有id 10 的owner 记录时,我希望以下代码返回一个元组{:error, changeset}:
House.changeset(%House{}, %{name: "Whatever", owner_id: 10}) |> Repo.insert
但是,我收到 Postgrex.Error:
** (Postgrex.Error) ERROR 23503 (foreign_key_violation): insert or update on table "house" violates foreign key constraint "house_owner_id_fkey".
如果我在调用Repo.insert 之前检查changeset.constraints 的内容,这就是我得到的:
House.changeset(%House{}, %{name: "Whatever", owner_id: 10})
|> Map.get(:constraints)
[
%{
constraint: "house_owner_id_fkey",
error: {"does not exist", []},
field: :owner_id,
match: :exact,
type: :foreign_key
}
]
那么,当使用 foreign_key_constraint 时,我不应该得到一个元组 {:error, changeset},我可以按照文档的建议进行模式匹配吗?
更新:
我没有使用 Ecto 的迁移。数据库表已经创建,迁移由不同的项目处理。 SQL Schema 如下所示:
Column | Type | Modifiers
---------------+---------+-------------------------------------------------------
id | integer | not null default nextval('house_id_seq'::regclass)
owner_id | integer | not null
Indexes:
"house_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"house_owner_id_fkey" FOREIGN KEY (owner_id) REFERENCES owner(id) DEFERRABLE INITIALLY DEFERRED
【问题讨论】:
标签: postgresql elixir ecto