我敢肯定,我失去了一些东西在这里,但我拉我的头发了这一点。我有以下模式的设置:
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
schema "accounts_users" do
field :name, :string
field :username, :string
field :nickname, :string
field :email, :string
field :avatar_url, :string
has_many :providers, Polydoc.Accounts.Provider, on_delete: :delete_all
timestamps()
end
schema "repositories_repositories" do
field :name, :string
field :description, :string
field :fork, :boolean
field :private, :boolean
field :write_permission, :boolean
field :uid, :string
field :owner_name, :string
belongs_to :provider, Polydoc.Accounts.Provider
end
我试图插入一条记录到accounts_providers
表,但运行到一个约束错误,但错误的引用存在于repositories_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)
当我尝试和运行UPSERT查询这是触发:
provider = Provider.oauth_changeset(%Provider{}, attrs)
Repo.insert(provider, on_conflict: :replace_all, conflict_target: [:uid, :provider])
其中provider
是
#Ecto.Changeset<
action: nil,
changes: %{
auth_token: "5ab9b61181eb3bc8221310eb4121a861ebb5b0a8",
provider: "github",
uid: "1657075",
user_id: 1
},
errors: [],
data: #Polydoc.Accounts.Provider<>,
valid?: true
>
任何线索,为什么我打这个错误,即使约束是对另一个表?我知道我没有foreign_key_constraint
在我的变更,但这对我来说并没有解释从错误的表上的错误
编辑
下面是该Provider
模式的变更功能
def oauth_changeset(%__MODULE__{} = provider, attrs) do
provider
|> cast(attrs, [:provider, :uid, :auth_token, :user_id])
|> validate_required([:provider, :uid, :auth_token])
|> unique_constraint(:provider_uid, name: :accounts_providers_uid_provider_index)
|> foreign_key_constraint(:user_id)
end
好它了 - 它涉及到外生处理on_conflict
功能的insert/2
选择的方式。如果设置为:replace_all
为我的是,它的字面取代这将似乎包括主键这反过来又通过使现有记录ID无效打破了我的其他表的外键的一切。
要解决,我已经改变了insert语句包括指定的字段,而不是取代:
Repo.insert(provider,
on_conflict: { :replace, [:auth_token, :updated_at]},
conflict_target: [:uid, :provider])