Elixir 不同架构上的EXTO约束错误

Elixir 不同架构上的EXTO约束错误,elixir,ecto,Elixir,Ecto,我很确定我错过了一些东西,但我正在为此烦恼。我有以下架构的设置: schema "accounts_providers" do field :provider, :string, null: false field :uid, :string, null: false field :auth_token, Persistence.Encrypted.Binary, null: false belongs_to :user, MyApp.Accounts.User times

我很确定我错过了一些东西,但我正在为此烦恼。我有以下架构的设置:

schema "accounts_providers" do
  field :provider, :string, null: false
  field :uid, :string, null: false
  field :auth_token, Persistence.Encrypted.Binary, null: false

  belongs_to :user, MyApp.Accounts.User
  timestamps()
end
我试图将一条记录插入
accounts\u providers
表,但遇到了一个约束错误,但该错误引用了
repositories\u repositories
表中存在的约束,我认为我没有触及该约束

[debug] QUERY ERROR db=32.6ms queue=9.5ms
INSERT INTO "accounts_providers" ("auth_token","provider","uid","user_id","inserted_at","updated_at") VALUES ($1,$2,$3,$4,$5,$6) ON CONFLICT ("uid","provider") DO UPDATE SET "id" = EXCLUDED."id","provider" = EXCLUDED."provider","uid" = EXCLUDED."uid","auth_token" = EXCLUDED."auth_token","user_id" = EXCLUDED."user_id","inserted_at" = EXCLUDED."inserted_at","updated_at" = EXCLUDED."updated_at" RETURNING "id" [<<1, 10, 65, 69, 83, 46, 71, 67, 77, 46, 86, 49, 217, 158, 158, 208, 9, 91, 16, 111, 110, 135, 12, 82, 201, 8, 126, 181, 141, 227, 56, 145, 148, 2, 217, 50, 202, 36, 4, 85, 228, 160, 42, 249, 38, 24, 135, 59, 235, ...>>, "github", "1657075", 1, ~N[2019-02-03 09:42:39], ~N[2019-02-03 09:42:39]]
[info] Sent 500 in 1980ms
[error] #PID<0.586.0> running PolydocWeb.Endpoint (cowboy_protocol) terminated
Server: app.lvh.me:4000 (http)
Request: GET /auth/github/callback?code=5bf8f2761b6d3892054f
** (exit) an exception was raised:
    ** (Ecto.ConstraintError) constraint error when attempting to insert struct:

    * repositories_repositories_provider_id_fkey (foreign_key_constraint)

If you would like to stop this constraint violation from raising an
exception and instead add it as an error to your changeset, please
call `foreign_key_constraint/3` on your changeset with the constraint
`:name` as an option.

The changeset defined the following constraints:

    * accounts_providers_user_id_fkey (foreign_key_constraint)
    * accounts_providers_uid_provider_index (unique_constraint)
其中
提供程序

#Ecto.Changeset<
  action: nil,
  changes: %{
    auth_token: "5ab9b61181eb3bc8221310eb4121a861ebb5b0a8",
    provider: "github",
    uid: "1657075",
    user_id: 1
  },
  errors: [],
  data: #Polydoc.Accounts.Provider<>,
  valid?: true
>

好的,我想出来了-这与EXTO处理
insert/2
函数的
on\u冲突
选项的方式有关。如果设置为
:replace_all
,就像我的一样,它实际上会替换所有看起来包含主键的内容,主键反过来会破坏另一个表的外键,使现有记录的id无效

为了修复此问题,我已将insert语句更改为包含指定要替换的字段:

Repo.insert(provider,
            on_conflict: { :replace, [:auth_token, :updated_at]},
            conflict_target: [:uid, :provider])

好的,我想出来了-这与EXTO处理
insert/2
函数的
on\u冲突
选项的方式有关。如果设置为
:replace_all
,就像我的一样,它实际上会替换所有看起来包含主键的内容,主键反过来会破坏另一个表的外键,使现有记录的id无效

为了修复此问题,我已将insert语句更改为包含指定要替换的字段:

Repo.insert(provider,
            on_conflict: { :replace, [:auth_token, :updated_at]},
            conflict_target: [:uid, :provider])
对我来说,解决办法是

Repo.insert_or_update(provider, 
    on_conflict:[
       set: [
         auth_token: auth_token, 
         updated_at: update_at
       ]
    ], 
    conflict_target: [:uid, :provider])
对我来说,解决办法是

Repo.insert_or_update(provider, 
    on_conflict:[
       set: [
         auth_token: auth_token, 
         updated_at: update_at
       ]
    ], 
    conflict_target: [:uid, :provider])

您是否也可以发布变更集功能。如果您获取生成的SQL并在数据库中手动运行,会发生什么情况?@MaartenvanVliet我已经添加了变更集函数HMM刚刚检查了SQL,似乎Ecto正在尝试设置冲突记录的id,而数据库中应该存在冲突,因此猜测,它试图将ID更新为不同的内容,从而导致另一个表中的外键约束无效。您是否也可以发布变更集函数。如果您获取生成的SQL并在数据库中手动运行,会发生什么情况?@MaartenvanVliet我已经添加了变更集函数HMM刚刚检查了SQL,似乎Ecto正在尝试设置冲突记录的id,而数据库中应该存在冲突,因此猜测,它试图将ID更新为其他内容,从而导致另一个表中的外键约束无效
Repo.insert(provider,
            on_conflict: { :replace, [:auth_token, :updated_at]},
            conflict_target: [:uid, :provider])
Repo.insert_or_update(provider, 
    on_conflict:[
       set: [
         auth_token: auth_token, 
         updated_at: update_at
       ]
    ], 
    conflict_target: [:uid, :provider])