psycopg2未返回结果

21
我正在尝试使用psycopg2与我的postgresql数据库配合使用,它只运行在我的本地计算机上,但无论我尝试什么都无法返回结果。它似乎可以连接到数据库,因为如果我更改任何配置参数,它就会抛出错误,但是当我运行看起来有效且值得返回结果的查询时,却什么也没有得到。
我的数据库正在运行,并且其中肯定有一个表:
postgres=# \c
You are now connected to database "postgres" as user "postgres".
postgres=# select * from foos;
  name   | age 
---------+-----
 Sarah   |  23
 Michael |  35
 Alice   |  12
 James   |  20
 John    |  52
(5 rows)

我的Python代码连接到了这个数据库,但无论我运行什么查询,都会得到None

Python 2.7.3 (default, Apr 10 2013, 06:20:15) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import psycopg2
>>> conn = psycopg2.connect("dbname='postgres' user='postgres' host='localhost'")
>>> cur = conn.cursor()
>>> print cur.execute("select * from foos;")
None
>>> print cur.execute("select * from foos")
None
>>> print cur.execute("select name from foos")
None
>>> print cur.execute("select f.name from foos f")
None

我是否做错了什么显而易见的事情?我该如何开始调试,因为它已经成功连接,所以不知道从哪里开始?


1
http://www.python.org/dev/peps/pep-0249/ - Ry-
4个回答

32

cursor.execute 准备和执行查询,但不获取任何数据,因此预期返回类型为 None。如果您想检索查询结果,必须使用其中一个 fetch* 方法:

print cur.fetchone()

rows_to_fetch = 3
print cur.fetchmany(rows_to_fetch)

print cur.fetchall()

4
游标的 execute() 方法只是执行你传递给它的 SQL 语句。然后,你有几个选项来获取游标的响应。你可以使用 fetchone() 方法返回下一个结果。第一次调用时,你将获得第一个结果,第二次是第二个结果,以此类推。而 fetchall() 方法则返回所有行,并可用作迭代器。
示例:
>>> # This is an example of the fetchone() method
>>> cur.execute("select * from foos")
>>> # This call will return the first row 
>>> result = cur.fetchone()
>>> # This call will return the second row
>>> result = cur.fetchone()


>>> # This is an example of the fetchall() method
>>> cur.execute("select * from foos")
>>> results = cur.fetchall()
>>> for r in results:
...     print r
>>> # Now we'll reset the cursor by re-executing the query
>>> cur.execute("select * from foos")
>>> for r in cur.fetchall():
...     print r

4
注意,正如文档中所述:http://initd.org/psycopg/docs/cursor.html“光标对象是可迭代的,因此,可以使用对象本身而不是在循环中显式调用fetchone()函数。”
因此,写成以下形式同样有效:
>>> cur.execute("select foo, bar from foobars")
>>> for foo, bar in cur:
....    print foo, bar

不需要显式调用fetchone()。我们Python程序员应该偏爱简洁的代码,只要不影响理解,我认为这样更自然。


1
这在我的情况下似乎不起作用(返回None,我无法迭代)。 fetchall() 可以正常工作,但这将是更符合 Python 风格的方法。 - PritishC
我可能有些误解,因为即使在版本2.8.2中,对我来说cur也不可迭代,尽管文档表明它应该是可迭代的。我必须调用fetchone()fetchall()才能使cur成为除None以外的任何东西。 - Alexander
我的错误是在调用execute时将cur重新分配给一个新变量。cur = p.connect(host='h', database='d', user='u').cursor() cur.execute("select * from foo where name = 'bar'")然后cur是可迭代的:但如果你这样做q = cur.execute("select * from foo where name = 'bar'")q就不是可迭代的。 - Alexander

3

说实话,在页面中间放示例,而在顶部放大量的API参考文档,很容易被忽视... - Adam Hughes

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