Oracle autoload broken because of LONG_STRING

Issue #622 resolved
Former user created an issue

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)

  1. Former user Account Deleted

    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.

  2. Former user 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.

  3. Log in to comment