Oracle autoload broken because of LONG_STRING
Following table will fail to be auto loaded using the trunk with Oracle 10g
CREATE TABLE Z_TEST
(
ID NUMBER(22) PRIMARY KEY,
ADD_USER VARCHAR2(20) DEFAULT USER NOT NULL
)
It fails with:
>>> from sqlalchemy import *
>>> meta = BoundMetaData('oracle://scott:tiger@test_db')
>>> tbl = Table('z_test', meta, autoload=True)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "c:\gnu\src\sqlalchemy\lib\sqlalchemy\schema.py", line 162, in __call__
metadata.get_engine().reflecttable(table)
File "c:\gnu\src\sqlalchemy\lib\sqlalchemy\engine\base.py", line 869, in reflecttable
self.dialect.reflecttable(conn, table)
File "c:\gnu\src\sqlalchemy\lib\sqlalchemy\databases\oracle.py", line 340, in reflecttable
row = c.fetchone()
File "c:\gnu\src\sqlalchemy\lib\sqlalchemy\engine\base.py", line 1097, in fetchone
return self._process_row(row)
File "c:\gnu\src\sqlalchemy\lib\sqlalchemy\engine\base.py", line 1182, in _process_row
row = [i) for i in xrange(len(row))](sup._get_col(row,)
File "c:\gnu\src\sqlalchemy\lib\sqlalchemy\engine\base.py", line 1066, in _get_col
return rec[1](1).convert_result_value(row[rec[2](rec[2)], self.dialect)
File "c:\gnu\src\sqlalchemy\lib\sqlalchemy\databases\oracle.py", line 99, in convert_result_value
return value.read()
AttributeError: 'str' object has no attribute 'read'
>>>
From what I can tell ALL_TAB_COLUMNS view returns LONG as datatype for DATA_DEFAULT column. LONG is being classified as a OracleBinary according to source:/sqlalchemy/trunk/lib/sqlalchemy/databases/oracle.py line 194
if self.dbapi is not None:
self.ORACLE_BINARY_TYPES = [k) for k in ["BFILE", "CLOB", "NCLOB", "BLOB", "LONG_BINARY", "LONG_STRING"](getattr(self.dbapi,) if hasattr(self.dbapi, k)]
else:
self.ORACLE_BINARY_TYPES = []
Finally autodiscovery fails when value for the string is being read(). The quick fix was to remove "LONG_STRING" from the list of binary types but that is probably not the right solution.
It looks like the check was introduced during #435
Comments (5)
-
Account Deleted -
repo owner - changed milestone to 0.4.0
ive committed in changeset:3082, need to test though
-
repo owner - changed status to resolved
9f856b88f6695318e32842a88fddd8f645e5cda5 adds your test but I cant reproduce the bug; i tried even reversing the recent changes I made in 29291f4c326086a413064bc8e32acad911a33910 but still, the LONG_STRING type doesn't come up for me when using Oracle XE so i can't reproduce the failure here. nevertheless the same issue was reported in
#751so have added this change for 0.3 in 6741cc58cf7d9dcdcc0eb7955c6f15cb57ed1340 -
Account Deleted My test program has stopped failing long time ago.
I believe the problem was fixed in 3064. You have added hasattr(value, 'read') check that prevents the error. Removing LONG_STRING from ORACLE_BINARY_TYPES should not matter anymore.
-
repo owner - removed milestone
Removing milestone: 0.4.0 (automated comment)
- Log in to comment
Bug has been introduced in 1af29a42d2007037f5ea790a005d05dded7d43c1. I would say that LONG_STRING and LONG_BINARY should be removed from the list of binary types, because cx_Oracle returns their values as strings, not as LOBs, and they have no read methods.
Maybe I should point out something what I also saw in 1af29a42d2007037f5ea790a005d05dded7d43c1: in the {{{OracleExecutionContext.get_result_proxy()}}} where type in typemap gets changed into {{{OracleBinary}}} even for CLOB which is otherwise {{{OracleText}}}. I didn't investigate this further, so I don't know if this is significant or not. Sorry if I'm talking obvious.