由于 DB API 2 的工作方式(它从数据库中返回行的元组),再加上 Python 的怪癖,当您想用一个元素指定一个元组时,您需要添加一个逗号,您会得到这个结果。它与 PyGreSQL 关系不大。
所以,当你第一次这样做时,你会得到一个(命名的)元组序列seq
:
seq = cur.execute("SELECT id, customer_name FROM session_monitor")
然后,当您执行以下操作时,您将迭代该序列,同时将您在每次迭代中获得的行元组解包id
到and customer_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)
与上面循环的不同之处在于,这个循环没有 tuple unpacking。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 接口而不是 DB API 2,您可以这样做:
q = db.query('SELECT max(id) FROM session_monitor')
print(q.singlescalar())
该single()
方法获取单行,如fetchone()
,并singlescalar()
获取该行的第一列。