Python/Kercopg 2中主键错误处理

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (54)

使用Python 2.7

我有一个简单的python脚本,用于处理事务并将数据写入数据库。偶尔会有违反我的主键的插入。下面是一个错误示例

ERROR: duplicate key value violates unique constraint "encounter_id_pkey"
DETAIL:  Key (encounter_id)=(9012235) already exists.

这是在下一个插入。不是违规。

Inserting: 0163168~9024065
ERROR: current transaction is aborted, commands ignored until end of transaction block

第二个错误会重复每次插入。下面是一个简化的循环。我正在循环一个pandas数据框架,但它可能是任何循环。

conn = psycopg2.connect("dbname='XXXX' user='XXXXX' host='XXXX' password='XXXXX'")

cur = conn.cursor()

for i, val in df2.iteritems():
    try:
        cur = conn.cursor()
        cur.execute("""insert into encounter_id_table (
        encounter_id,current_date  )
        values       
        (%(create_date)s, %(encounter_id)s ) ;""",
        'encounter_id':i.split('~')[1],  
        'create_date': datetime.date.today() })           
        cur.commit()
        cur.close() 
    except Exception , e:
        print 'ERROR:', e[0]
        cur.close()
 conn.close()   

有什么东西我只是遗漏了吗?

提问于
用户回答回答于

我又加了一个try..except..else构造代码,以显示异常发生的确切位置。

try:
    cur = conn.cursor()

    try:
        cur.execute("""insert into encounter_id_table (
            encounter_id,current_date  )
            values       
            (%(create_date)s, %(encounter_id)s ) ;""",
            'encounter_id':i.split('~')[1],  
            'create_date': datetime.date.today() })
    except psycopg2.IntegrityError:
        conn.rollback()
    else:
        conn.commit()

    cur.close() 
except Exception , e:
    print 'ERROR:', e[0]
用户回答回答于

首先:CURRENT_DATE是每个SQL标准以及PostgreSQL中的保留字。如果没有双引号,就不能将它用作标识符。我强烈建议不要使用它。我将列重命名为curdate在我的例子中

接下来,我不是python语法方面的专家,但您似乎颠倒了插入列的顺序:

(%(create_date)s, %(encounter_id)s )

应:

( %(encounter_id)s, %(create_date)s)

对于您的主要问题:您可以通过在INSERT命令中使用键之前检查该键是否已经在表中来避免这个问题:

INSERT INTO encounter_id_table (encounter_id, curdate)
SELECT 1234, now()::date
WHERE  NOT EXISTS (SELECT * FROM encounter_id_table t
                   WHERE t.encounter_id = 1234);

在Python语法中,应该是:

cur.execute("""INSERT INTO encounter_id_table (encounter_id, curdate)
    SELECT %(encounter_id)s, %(create_date)s,
    WHERE  NOT EXISTS (
           SELECT * FROM encounter_id_table t
           WHERE t.encounter_id = %(encounter_id)s);""",
  {'encounter_id':i.split('~')[1],  
  'create_date': datetime.date.today()})       

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励