【问题标题】:Postgres says key already exists although it doesn'tPostgres 说密钥已经存在,尽管它不存在
【发布时间】: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


【解决方案1】:

经过一番挖掘,我发现我正在抓取的论坛有时会为给定线程返回错误的页面数。因此,当应用程序尝试抓取第 5 页(不存在)时,它会被重定向到第 4 页并尝试再次插入相同的帖子。因此完整性错误。

【讨论】:

    猜你喜欢
    • 2013-01-11
    • 2017-06-14
    • 1970-01-01
    • 2016-02-17
    • 2020-10-31
    • 1970-01-01
    • 2014-02-10
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多