【问题标题】:Ignore duplicate rows in PostgreSQL忽略 PostgreSQL 中的重复行
【发布时间】:2021-05-14 14:07:23
【问题描述】:

我正在使用 pythonpsycopg2 将字典插入到我的 PostgreSQL 数据库中。

我有 postgres 13.2 版

目前我只有下面的代码可以执行:

 INSERT INTO movie_data(title, description, rating, published, cast_and_crew, age_group, country)
 VALUES ('movie name', 'something', 8, 2020, 'an actor', 'pg-13', 'GB')

但因为我的数据库中已经有这一行,所以我得到 '已经存在' 错误。

我已经尝试了 ON CONFLICT DO NOTHING,但我收到以下错误:

there is no unique or exclusion constraint matching the ON CONFLICT specification

忽略重复行并继续插入的最佳方法是什么?

我是 SQL 的新手,所以如果有人能为此目的解释并包含整个代码,我将不胜感激。

更新:下面是我的CREATE TABLE 声明

CREATE TABLE public.movie_data
(
    title text COLLATE pg_catalog."default" NOT NULL,
    description text COLLATE pg_catalog."default" NOT NULL,
    published integer,
    cast_and_crew text COLLATE pg_catalog."default",
    age_group text COLLATE pg_catalog."default",
    country text COLLATE pg_catalog."default",
    rating integer,
    CONSTRAINT movie_data_pkey PRIMARY KEY (title, description)
)

TABLESPACE pg_default;

ALTER TABLE public.movie_data
    OWNER to postgres;

【问题讨论】:

  • 请显示带有所有约束的CREATE TABLE 语句。你没有主键吗?
  • 我已经有了表,我只想往里面插入数据。
  • 我也只在标题和描述上设置了主键
  • 带有ON CONFLICT 子句的完整INSERT 语句是什么?使用此信息更新您的问题。

标签: python postgresql


【解决方案1】:

错误很明显,您需要对需要唯一的列在表上设置唯一约束

alter table movie_data
add constraint constraintname unique (title, description); 

现在你可以使用这个约束了:

 INSERT INTO movie_data(title, description, rating, published, cast_and_crew, age_group, country)
 VALUES ('movie name', 'something', 8, 2020, 'an actor', 'pg-13', 'GB')
 on conflict on constraint constraintname do nothing;

正如 Adrian 指出的那样,如果您的主键位于那些需要唯一的列上,那么您可以:

 INSERT INTO movie_data(title, description, rating, published, cast_and_crew, age_group, country)
 VALUES ('movie name', 'something', 8, 2020, 'an actor', 'pg-13', 'GB')
 on conflict (title, description) do nothing;

【讨论】:

  • 因为你已经有一个PRIMARY KEY(标题,描述)你可以跳过这个,直接做ON CONFLICT (title, description) DO NOTHING
  • @eshirvana 非常感谢,现在可以工作了 :)
【解决方案2】:

为什么你想要一个包含重复行的主键?主键的主要目的是唯一标识行。

我认为你应该放弃你的主键:

alter table public.movie_data drop constraint movie_data_pkey;

【讨论】:

  • 您似乎误解了@AryanHab 试图实现的目标。也就是说,通过使用ON CONFLICT DO NOTHING 跳过与现有行重复的任何行的INSERT,不会有重复的行。这通常称为UPSERT,尽管它更准确地描述了另一个选项:ON CONFLICT DO UPDATE。放弃PK不是答案。
  • 我认为他不是这个意思。 “继续插入”他写道,这并不意味着更新。
  • 整个引用是:“忽略重复行并继续插入的最佳方法是什么?”所以@AryanHab 选择通过使用DO NOTHING 忽略任何重复行的INSERT,然后继续处理不是重复行的INSERTs。这就是为什么它不是我提到的真正的UPSERT
  • 嗯,UPSERT 是最准确的推理。
猜你喜欢
  • 2015-05-25
  • 2012-12-06
  • 1970-01-01
  • 2020-01-03
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
  • 2018-06-01
  • 2014-09-25
相关资源
最近更新 更多