Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cx_Oracle: How can I receive each row as a dictionary?

By default, cx_Oracle returns each row as a tuple.

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

How can I return each row as a dictionary?

like image 650
Mark Harrison Avatar asked Jan 27 '16 19:01

Mark Harrison


2 Answers

You can override the cursor's rowfactory method. You will need to do this each time you perform the query.

Here's the results of the standard query, a tuple.

curs.execute('select * from foo')
curs.fetchone()
    (33, 'blue')

Returning a named tuple:

def makeNamedTupleFactory(cursor):
    columnNames = [d[0].lower() for d in cursor.description]
    import collections
    Row = collections.namedtuple('Row', columnNames)
    return Row

curs.rowfactory = makeNamedTupleFactory(curs)
curs.fetchone()
    Row(x=33, y='blue')

Returning a dictionary:

def makeDictFactory(cursor):
    columnNames = [d[0] for d in cursor.description]
    def createRow(*args):
        return dict(zip(columnNames, args))
    return createRow

curs.rowfactory = makeDictFactory(curs)
curs.fetchone()
    {'Y': 'brown', 'X': 1}

Credit to Amaury Forgeot d'Arc: http://sourceforge.net/p/cx-oracle/mailman/message/27145597

like image 187
Mark Harrison Avatar answered Sep 20 '22 09:09

Mark Harrison


A very short version:

curs.rowfactory = lambda *args: dict(zip([d[0] for d in curs.description], args))

Tested on Python 3.7.0 & cx_Oracle 7.1.2

like image 41
maelcum73 Avatar answered Sep 22 '22 09:09

maelcum73