【发布时间】:2015-11-06 17:28:48
【问题描述】:
我的 Python 应用程序使用 Psycopg2 将来自网络爬虫的内容插入 PostgreSQL 数据库。 Psycopg2 抱怨某个主键已经存在,尽管它显然不存在。
错误:
psycopg2.IntegrityError: duplicate key value violates unique constraint "my_table_pkey"
DETAIL: Key (id)=(12345) already exists.
查询:
SELECT * FROM my_table where id=12345;
-- 0 rows returned
这是怎么回事?
编辑背景:
基本上,代码的作用是抓取一个讨论论坛,遍历每个讨论线程中的每个页面,并将每个线程中的一些数据插入 Postgres。代码的一般结构概述如下。请注意,get 会为每个线程返回一个格式良好的数据结构。
import psycopg2
base_url 'http://someforum.com'
conn = psycopg2.connect('dbname=mydb user=me')
for i in range(10000):
thread = get('{}/'{}.format(base_url, i)
for page in thread:
sql = 'INSERT INTO my_table (id, foo, bar) VALUES(%s, %s, %s);'
values = [page['id'], page['foo'], page['bar']]
cur.execute(sql, values)
conn.commit()
cur.close()
conn.close()
【问题讨论】:
-
要么 1) 您在一个广泛使用且经过大量测试的软件产品中发现了一个完全明显且相对严重的错误(干得好!),或者 2) 您的代码中的某些内容导致 PostgreSQL 抛出完全合理的错误。在我 40 多年的软件开发中,我曾多次认为自己遇到过 (1)。除了一旦它被证明是(2)。如果没有看到更多代码,就不可能确切地说出发生了什么,但您可能要考虑这种情况 (1) 不太可能。也许如果您发布更多代码,我们可以提供更多帮助。谢谢。
-
@BobJarvis:这是一种非常友好和有趣的方式来说明这个问题在没有大部分相关信息的情况下基本上是无用的。
-
您的代码插入了两次?没有代码这是没用的,我投票关闭
-
@trevorDashDash - 最可能的问题是 INSERT 使用相同的 ID 值执行了两次。发生错误后,您将不会在
my_table中找到多行id= 12345,因为事务已回滚。也可能是数据库中的触发器正在执行另一个 INSERT,这可能会产生相同的结果。如果您编辑问题并包含所有正在执行的代码,这将有所帮助 - 请参阅How to create a Minimal, Complete, and Verifiable example。谢谢。 -
毫无疑问,您的循环对
page['id']使用了两次相同的值,并且由于该错误,整个事务被回滚,这意味着根本没有插入任何内容。
标签: postgresql psycopg2