【问题标题】:ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification错误:没有与 ON CONFLICT 规范匹配的唯一或排除约束
【发布时间】:2021-06-18 18:52:31
【问题描述】:

我正在尝试对名为 feature_to_model 的表执行 upsert。但是,我收到以下错误:

ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification (SQLSTATE 42P10)

这是我的桌子规格:

CREATE TABLE IF NOT EXISTS feature_to_model (
training_job_id     varchar NOT NULL,
feature_name        varchar NOT NULL,
feature_set_name    varchar NOT NULL,
model_name          varchar NOT NULL,
created_at          timestamp with time zone DEFAULT now() NOT NULL,
PRIMARY KEY (training_job_id, feature_name, feature_set_name)

我使用 Gorm 来查询数据库,这是我的函数调用:

func (s *store) UpsertFeatureToModel(f2m *model.FeatureToModel) (*model.FeatureToModel, error) {
    result := s.db.Table(f2mTable).Clauses(clause.OnConflict{
        UpdateAll: true,
    }).Create(f2m)
    if result.Error != nil {
        return nil, result.Error
    }
    return f2m, nil
}

我错过了什么?我不能对任何索引使用 UNIQUE 约束(training_job_id、feature_name、feature_set_name 是索引),因为它们都不是唯一的

【问题讨论】:

  • 这 3 列是唯一的。您已将它们定义为主键,根据定义,它必须是唯一的。在本机 Postgres 中,您将指定 on conflict(training_job_id, feature_name, feature_set_name)。我不确定你是如何在你的模糊模型中做到这一点的,但这就是你所需要的。

标签: sql postgresql go go-gorm


【解决方案1】:

错误:没有与 ON CONFLICT 规范匹配的唯一或排除约束

这是因为 training_job_id 是 FOREIGN KEY CONSTRAINT 中引用的列,而不是索引。事实上,如果你想让它更快,你可以考虑额外添加一个索引。来自 ON CONFLICT 上的文档

你可能想要这样的东西,

CREATE TABLE IF NOT EXISTS feature_to_model (
training_job_id     varchar NOT NULL,
feature_name        varchar NOT NULL,
feature_set_name    varchar NOT NULL,
model_name          varchar NOT NULL,
created_at          timestamp with time zone DEFAULT now() NOT NULL,
PRIMARY KEY (training_job_id, feature_name, feature_set_name)
CONSTRAINT UC_feature_to_model UNIQUE (training_job_id)

【讨论】:

  • 此表规范可防止该错误,但是,当我尝试插入新行时,它并不能完全按照我的意愿执行。假设我想插入(id1,feature1,featureSet1)和(id1,feature2,featureSet2),它们是唯一的,但不是单独的,所以在第二次插入后,第一个的行被更新,但我想要单独的行对于两个插入。我尝试将其他列放在 UNIQUE 子句中,但效果不佳...@Yahampath
  • 是的,应该是,原因是您正在执行 upsert 并且两个记录 id 相同。所以 mongo 没有将其识别为新记录。因此,在 feature_to_model 集合中为自己创建一个 id 字段,并将该键设为主键。然后使用 training_job_id 作为外键。我打洞这会解决你的问题。 @Khashhogi
猜你喜欢
  • 2021-12-21
  • 2019-08-03
  • 2016-08-03
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 2016-08-08
  • 2019-09-19
相关资源
最近更新 更多