python pgdb挂数据库

时间:2011-10-06 01:15:49

标签: python postgresql pgdb

我正在编写一个脚本来访问已建立的数据库中的数据,不幸的是,我正在破坏数据库。我可以从命令行重新创建问题:

    [user@box tmp]# python
    Python 2.7.2 (default, Sep 19 2011, 15:02:41) 
    [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import pgdb
    >>> db = pgdb.connect('localhost:my_db:postgres')
    >>> cur = db.cursor()
    >>> cur.execute("SELECT * FROM mytable LIMIT 10")
    >>> cur.close()
    >>> 

此时,对mytable的任何活动都会大大降低,“select * from pg_stat_activity”会将我的连接显示为“在事务中的IDLE”。如果我调用db.close()一切都很好,但我的脚本无限循环,我不认为我需要打开和关闭每个循环的数据库连接。我不认为它与我不使用上面的数据这一事实有关,因为在我的真实脚本中我调用fetchone()(在循环中)来处理数据。我不是一个数据库人,所以我不确定其他信息会有用。我的postgres版本是9.1.0,python是2.7.2,如上所示。

2 个答案:

答案 0 :(得分:1)

在关闭光标之前尝试调用db.rollback()(或者如果您正在执行写操作db.commit())。

答案 1 :(得分:1)

我建议使用psycopg2而不是pgdb。 pgdb使用以下语义:

connect() - >打开数据库连接,开始交易
commit() - >提交,开始交易
rollback() - >回滚,开始交易
execute() - >执行声明

另一方面,

psycopg2使用以下语义:

connect() - >打开数据库连接
commit() - >提交
rollback() - >回滚
execute() - >除非已在事务中,否则开始事务,执行语句

因此,正如Amber所提到的,您可以在select语句之后执行回滚或提交并终止事务。不幸的是,使用pgdb,您将在回滚或提交后立即启动一个新事务(即使您没有执行任何工作)。

对于许多数据库系统,pgdb的行为很好,但由于PostgreSQL处理事务的方式,如果你有很多连接访问相同的表(特别是真空故障),它会给你带来麻烦。

为什么pgdb会马上开始交易? Python DB-API(2.0)规范要求它这样做。对我来说似乎有些愚蠢,但这就是编写规范的方式。