python - PyGreSQL 为一列选择语句返回意外结果

标签 python python-db-api pygresql

我有以下 PostgreSQL 数据库表:

TABLE session_monitor
(
    id int,
    customer_name varchar(150)
)

当我运行以下代码时:

seq = pg_cur.execute("SELECT id ,customer_name from session_monitor")
for id, customer_name in seq:
    print(id)
    print(customer_name)

它工作正常。

但是当我尝试

pg_cur.execute("SELECT max(id) as max_id from session_monitor")
for max_id in seq:
    print(max_id)

我没有得到数字,而是:Row(max_id= 5)

我尝试了一种解决问题的方法:

seq = pg_cur.execute("SELECT max(id) as max_id,1 as one from session_monitor")
for max_id, one in seq:
    print(max_id)

但这样使用它似乎有些蹩脚。

我在这里做错了什么 - 在第二种情况下是否有不同的方法来迭代查询结果?

最佳答案

之所以会得到这个结果,是因为 DB API 2 的工作方式(它从数据库中返回行的元组),再加上 Python 的怪癖,即当您想要指定一个包含一个元素的元组时,您需要添加一个逗号。它与 PyGreSQL 关系不大。

所以,当你第一次这样做时,你会在 seq 中得到一个(命名的)元组序列:

seq = cur.execute("SELECT id, customer_name FROM session_monitor")

然后当您执行以下操作时,您将遍历该序列同时解包您在每次迭代中获得的行元组到 idcustomer_name :

for id, customer_name in seq:
    print(id)
    print(customer_name)

当您只选择一列时,就像这样,您仍然得到一系列(命名的)元组,每个元组只有一个元素:

seq = cur.execute("SELECT max(id) AS max_id FROM session_monitor")

现在您尝试像这样迭代序列:

for max_id in seq:
    print(max_id)

与上面的循环不同的是,这个循环不进行元组解包。所以 max_id 将是打印的完整行。

要像上面那样使用元组解包,您需要在 max_id 之后添加一个逗号:

for max_id, in seq:
    print(max_id)

这将打印出您所期望的。顺便说一句,您还可以在元组解包表达式周围添加括号。但是,如果一个元组只有一个元素,您仍然需要一个逗号。

当然,如果你只有一行一列,你可以这样做:

seq = cur.execute("SELECT max(id) AS max_id FROM session_monitor")
max_id = list(seq)[0][0]
print(max_id)

或者,也可以使用 fetchone() 方法:

cur.execute("SELECT max(id) as max_id FROM session_monitor")
max_id = cur.fetchone()[0]
print(max_id)

当然,您也可以利用命名元组这一事实:

cur.execute("SELECT max(id) as max_id from session_monitor")
print(cur.fetchone().max_id)

作为旁注,使用“经典”PyGreSQL 接口(interface)而不是 DB API 2,您可以这样做:

q = db.query('SELECT max(id) FROM session_monitor')
print(q.singlescalar())

single() 方法获取单行,如 fetchone()singlescalar() 获取该行的第一列。

关于python - PyGreSQL 为一列选择语句返回意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62025882/

相关文章:

python - 取消 Python 脚本时做一些事情

python - Python DB-API 2.0 仅适用于关系数据库吗?

python - 为什么 Python 的 DB-API 中的连接没有 "begin"操作?

python - 如何在对象列表中搜索属性?

python - mypy 错误 - 尽管使用了 'Union',但类型不兼容

python - python 线程问题 (dht22)

python - 使用 Python 将 JSON 插入 MySQL

python - 使用pygresql(pg模块)执行SQL select in语句

python - 如何从 pygresql 捕获特定异常?

python - 使用 PygreSQL v5.0.6 将 None 值插入从 python 到 PostgreSQL 数据库的 Date 列