I have the following PostgreSQL database table:
TABLE session_monitor
(
id int,
customer_name varchar(150)
)
When I am running the following code:
seq = pg_cur.execute("SELECT id ,customer_name from session_monitor")
for id, customer_name in seq:
print(id)
print(customer_name)
it is working fine.
But when I try
pg_cur.execute("SELECT max(id) as max_id from session_monitor")
for max_id in seq:
print(max_id)
I am not getting a number, but rather: Row(max_id= 5)
I tried a workaround that sort of solves the problem:
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)
but it seems kind of lame to use it like this.
What am I doing wrong here - is there a different way to iterate the query result in the second case?
You get this result due to the way how DB API 2 works (it returns tuples for rows from the database), combined with the Python quirk that you need to add a comma when you want to specify a tuple with one element. It has little to do with PyGreSQL.
So, when you first do this, you get a sequence of (named) tuples in
seq:When you then do the following, you iterate over that sequence while unpacking the row tuple you get in each iteration to
idandcustomer_name:When you only select one column, like this, you still get a sequence of (named) tuples, with only one element per tuple:
Now you tried to iterate over the sequence like this:
The difference to the loop above is that this one does no tuple unpacking. So
max_idwill be the complete row, which is printed.To make use of tuple unpacking like above, you need to add a comma after the
max_id:This will print what you expected. Btw, you can also add parens around the tuple unpacking expression. However, you still need a comma if a tuple only has one element.
Of course, if you only get one row with one column, you could just do:
Or, alternatively, using the
fetchone()method:And of course, you can also make use of the fact that you get named tuples:
As a side note, using the "classic" PyGreSQL interface instead of DB API 2, you would do this:
The
single()method gets a single row likefetchone(), andsinglescalar()gets the first column of that row.