Как получить каждую запись результата как словарь?

При получении результата из курсора, каждая запись возвращается как кортеж:

>>> import cx_Oracle
>>> conn=cx_Oracle.connect('scott/tiger')
>>> curs=conn.cursor()
>>> curs.execute("select 33, 'blue' from dual");
>>> curs.fetchone()
(33, 'blue')

Как сделать так, чтобы получать каждую запись как словарь?


Свободный перевод вопроса cx_Oracle: How can I receive each row as a dictionary? от участника @Mark Harrison


Ответы (1 шт):

Автор решения: 0xdb

Согласно документации, достаточно записать в следующий атрибут фукцию, которая будет вызвана для каждой записи результата:

Cursor.rowfactory

This read-write attribute specifies a method to call for each row that is retrieved from the database. Ordinarily a tuple is returned for each row but if this attribute is set, the method is called with the tuple that would normally be returned, and the result of the method is returned instead.

Воспроизводимый пример:

from cx_Oracle import connect 

with connect ('connect string').cursor () as cursor:
    cursor.execute("""
        select 'key'||rownum key, 'value'||rownum value 
        from dual connect by level<=3
        """)
    columns = [col[0].lower () for col in cursor.description]
    cursor.rowfactory = lambda *args: dict (zip (columns, args))
    row = cursor.fetchone ()     
    print (row)
    from collections import namedtuple
    cursor.rowfactory = namedtuple('Row', columns)
    row = cursor.fetchone ()     
    print (row)
    cursor.rowfactory = None 
    row = cursor.fetchone ()      
    print (row)

Результат:

{'key': 'key1', 'value': 'value1'}
Row(key='key2', value='value2')
('key3', 'value3')

→ Ссылка