Python psycopg2 无法将数据插入到 PostgreSQL 表中

63

我正在尝试向PostgreSQL数据库表中插入记录,但是它没有起作用。 我没有收到任何错误消息,但是表中没有记录。 我需要提交或其他什么吗? 我正在使用与Bitnami djangostack安装一起安装的PostgreSQL数据库。

import psycopg2

try:
    conn = psycopg2.connect("dbname='djangostack' user='bitnami' host='localhost' password='password'")
except:
    print "Cannot connect to db"

cur = conn.cursor()

try:
    cur.execute("""insert into cnet values ('r', 's', 'e', 'c', 'w', 's', 'i', 'd', 't')""")
except:
    print "Cannot insert"

3
警告:捕获未指定特定异常的 except: 子句对于调试代码毫无帮助。 - mechanical_meat
4
在许多情况下,建议将autocommit设置为False。因此,在执行查询后手动提交:在cursor.execute()之后执行conn.commit()。 - MinhajulAnwar
请查看此帖子中的答案:链接 - Inaam Ilahi
4个回答

115
如果不想每次都将条目提交到数据库中,您可以添加以下行:
conn.autocommit = True

因此,您最终的代码将是:
import psycopg2

try:
    conn = psycopg2.connect("dbname='djangostack' user='bitnami' host='localhost' password='password'")
    conn.autocommit = True
except:
    print "Cannot connect to db"

cur = conn.cursor()

try:
    cur.execute("""insert into cnet values ('r', 's', 'e', 'c', 'w', 's', 'i', 'd', 't')""")
except:
    print "Cannot insert"

嗨,你知道如果没有将autocommit设置为True并且从未提交会发生什么吗?似乎表的序列会增加,但是行在哪里呢? - Daniel Baughman
2
@DanielBaughman:这是因为序列即使您不提交也会递增;请参见例如Sequences not affected by transactions? - user1071847

55

结果发现我需要在结尾处使用 conn.commit()


38

psycopg2 遵循 Python DB API,因此默认情况下自动提交功能已关闭。您需要调用conn.commit 来提交任何待处理的事务到数据库中。由于连接(和游标)是上下文管理器,所以您可以使用 with 语句来在离开上下文时自动提交/回滚事务:

with conn, conn.cursor() as cur:  # start a transaction and create a cursor
    cur.execute(sql)

来自文档

with语句块结束时,如果没有异常被抛出,则提交事务。在发生异常的情况下,回滚事务。

with语句块结束时,游标关闭,释放与其相关的任何资源。事务的状态不会受到影响。


3
谢谢您的肯定,我认为这是最好、最简洁的答案。 - mad.meesh
1
这很棒。我从一个函数中获取连接,并且能够实现以下代码: with get_connection(self.database_name, self.user_name) as conn, conn.cursor() as csr: csr.execute(statement)这意味着即使第一个值没有预定义,我也可以引用with语句中第二个值的第一个值。 - DonkeyKong
1
@DonkeyKong 在 with 块之后可能需要单独调用 conn.close() - lk_vc

6
import psycopg2
conn = psycopg2.connect("dbname='djangostack' user='bitnami' 
host='localhost' password='password'")
con.set_session(autocommit=True)

7
请勿发布仅包含代码的回答,这种回答在一段时间内理解上下文方面的帮助将较少。换句话说,即使是最好的回答,如果对社区来说难以理解,也不会得到点赞。请确保您的回答能够让大家轻松理解,谢谢! - Arun Vinoth-Precog Tech - MVP
2
嗯,只发布代码也没什么问题。有时候,这是回答问题的一种非常好看和漂亮的方式。但是,我认为那并没有完全回答OP所问的问题。 - dtc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接