PyGre SQL возвращает неожиданный результат для оператора выбора одного столбца - PullRequest
3 голосов
/ 26 мая 2020

У меня есть следующая таблица базы данных 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)

, но использовать его в таком виде кажется некрасивым.

Что я здесь делаю не так - есть ли другой способ итерации результата запроса во втором случае?

1 Ответ

2 голосов
/ 26 мая 2020

Вы получаете этот результат из-за того, как работает DB API 2 (он возвращает кортежи для строк из базы данных), в сочетании с особенностью Python, когда вам нужно добавить запятую, когда вы хотите указать кортеж с одним элемент. Это не имеет ничего общего с PyGre SQL.

Итак, когда вы впервые сделаете это, вы получите последовательность (названных) кортежей в seq:

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

Когда вы затем выполните следующие действия: вы перебираете эту последовательность при распаковке кортежа строк, который вы получаете на каждой итерации, до id и 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)

Отличие от l oop выше в том, что этот не распаковывает кортежей. Таким образом, 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)

В качестве примечания, используя интерфейс PyGre SQL classi c вместо DB API 2, вы должны сделать следующее:

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

Метод single() получает одну строку типа fetchone() и singlescalar() получает первый столбец этой строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...