在 PostgreSQL 中插入唯一值
Inserting unique values in PostgreSQL
我正在尝试在我的数据库中插入不同的值:
我的查询是这样的:
query2 = "INSERT INTO users (id, name, screenName, createdAt, defaultProfile, defaultProfileImage,\
description) SELECT DISTINCT %s, %s, %s, %s, %s, %s, %s;"
cur.execute(query2, (user_id, user_name, user_screenname, user_createdat, \
default_profile, default_profile_image, description))
但是,我仍然得到错误:psycopg2.IntegrityError:重复键值违反唯一约束"users_key"。
我猜查询是在插入所有数据然后选择不同的值?
我猜的另一种方法是将所有数据存储在一个临时数据库中,然后在那里检索它们。
但是有没有更简单的方法呢?
谢谢!
您似乎在尝试执行 insert ... if not exists
类型的操作。如果您使用的是 PostgreSQL 9.5,则应使用 INSERT ... ON CONFLICT NO ACTION
。有关详细信息,请参阅 How to UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE) in PostgreSQL?。
SELECT DISTINCT
,按照你的方式使用,不会帮你解决这个问题。它仅对输入到 SELECT
语句的行进行操作。它对输出行的去向一无所知,在您的情况下为 table.
您需要加入 table,或使用 WHERE NOT EXISTS (SELECT 1 FROM mytable WHERE ...)
使 INSERT INTO ... SELECT ...
的 SELECT
部分 return 为零行,如果该行目标 table.
中已经存在
不过请注意,这仍受竞争条件的影响。如果您有多个并发客户端,您还需要 LOCK
table.
对于任何正在寻找一种方法将唯一值从一个 table 插入到没有唯一键的 table 的人(换句话说,只插入行列与目标中现有记录的一组列不匹配 table)
例如
Table 1
column1 column2
------- -------
1. dog collar
Table 2
column1 column2
------- -------
1. dog collar
2. dog leash
预期效果是插入 Table 2 中的第 2 列,而不是第 1 列,因为它与 Table 1 中的一行匹配。
这对我有用,尽管性能不是很好:
INSERT INTO table1 (
column1,
column2
)
SELECT
column1,
column2
FROM table2
WHERE (
column1,
column2
)
NOT IN
(SELECT
column1,
column2
FROM table1)
我正在尝试在我的数据库中插入不同的值: 我的查询是这样的:
query2 = "INSERT INTO users (id, name, screenName, createdAt, defaultProfile, defaultProfileImage,\
description) SELECT DISTINCT %s, %s, %s, %s, %s, %s, %s;"
cur.execute(query2, (user_id, user_name, user_screenname, user_createdat, \
default_profile, default_profile_image, description))
但是,我仍然得到错误:psycopg2.IntegrityError:重复键值违反唯一约束"users_key"。
我猜查询是在插入所有数据然后选择不同的值? 我猜的另一种方法是将所有数据存储在一个临时数据库中,然后在那里检索它们。 但是有没有更简单的方法呢?
谢谢!
您似乎在尝试执行 insert ... if not exists
类型的操作。如果您使用的是 PostgreSQL 9.5,则应使用 INSERT ... ON CONFLICT NO ACTION
。有关详细信息,请参阅 How to UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE) in PostgreSQL?。
SELECT DISTINCT
,按照你的方式使用,不会帮你解决这个问题。它仅对输入到 SELECT
语句的行进行操作。它对输出行的去向一无所知,在您的情况下为 table.
您需要加入 table,或使用 WHERE NOT EXISTS (SELECT 1 FROM mytable WHERE ...)
使 INSERT INTO ... SELECT ...
的 SELECT
部分 return 为零行,如果该行目标 table.
不过请注意,这仍受竞争条件的影响。如果您有多个并发客户端,您还需要 LOCK
table.
对于任何正在寻找一种方法将唯一值从一个 table 插入到没有唯一键的 table 的人(换句话说,只插入行列与目标中现有记录的一组列不匹配 table)
例如
Table 1
column1 column2
------- -------
1. dog collar
Table 2
column1 column2
------- -------
1. dog collar
2. dog leash
预期效果是插入 Table 2 中的第 2 列,而不是第 1 列,因为它与 Table 1 中的一行匹配。
这对我有用,尽管性能不是很好:
INSERT INTO table1 (
column1,
column2
)
SELECT
column1,
column2
FROM table2
WHERE (
column1,
column2
)
NOT IN
(SELECT
column1,
column2
FROM table1)