Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Add support to XML type #14
The XML type is not supported on cx_Oracle. When I run a code like below, I get the error: AttributeError: 'cx_Oracle.OBJECT' object has no attribute 'read'
result = cursor.execute( """SELECT XMLElement("Date", hire_date) FROM hr.employees WHERE employee_id = 203""" ) for res in result: # The exception occours right here raw_xml = res.read()
But there are simple workaround. Just use the function GETCLOBVAL:
result = cursor.execute( """SELECT XMLElement("Date", hire_date).GETCLOBVAL() FROM hr.employees WHERE employee_id = 203""" ) for res in result: import xml.etree.ElementTree as ET xml_string = res.read() tree = ET.fromstring(xml_string)
The workaround works. But I think that would more pythonic if the cx_Oracle do this automatically:
result = cursor.execute( """SELECT XMLElement("Date", hire_date) FROM hr.employees WHERE employee_id = 203""" ) for res in result: xml = res.read() type(xml) # <class 'xml.etree.ElementTree.Element'>
XMLType is returned as an Oracle object with no attributes. It has functions that can only be called from SQL or PL/SQL -- which defeats the purpose! The workaround you have noted already works for you. Another one is to use an output type handler, as in this code:
import cx_Oracle def OutputTypeHandler(cursor, name, defaultType, size, precision, scale): if defaultType == cx_Oracle.OBJECT: return cursor.var(cx_Oracle.LONG_STRING, arraysize = cursor.arraysize) conn = cx_Oracle.Connection("cx_Oracle/dev@localhost/orcl") conn.outputtypehandler = OutputTypeHandler cursor = conn.cursor() cursor.execute("select XMLCol from testxml where rownum <= 1") row = cursor.fetchone() print(row) # will be returned as a string
I will look into making this happen automatically since the XMLType objects returned aren't helpful by themselves. In the meantime, hopefully this is a helpful addition.
I did some initial research last year and discussed with the XMLType group internally. A few enhancements to the OCI library are planned which will make working with this type simpler. In the meantime, however, I can look at better workarounds. Thanks for bringing it back to my attention. I'll take another look at it. :-)
I just created a patch to ODPI-C (which cx_Oracle depends on) which automatically intercepts SYS.XMLTYPE and returns a (LONG) string instead. It is awaiting internal review but I hope to have it available publicly in a few days. Thanks for your patience.