changes to Enum/SchemaType to re-support adaptation of string types.
This approach can be adapted by "conditional" unicode returning dialects
(i.e. pyodbc and possibly mxodbc) to remove the overhead
of isinstance(value, unicode) calls when the dialect returned type is
of dbapi.UNICODE, dbapi.NVARCHAR, etc.
return value
return process
-class _OracleChar(sqltypes.CHAR):
+class _NativeUnicodeMixin(object):
+ def result_processor(self, dialect, coltype):
+ # if we know cx_Oracle will return unicode,
+ # don't process results
+ if self.convert_unicode != 'force' and \
+ dialect._cx_oracle_native_nvarchar and \
+ coltype == dialect.dbapi.UNICODE:
+ return None
+ else:
+ return super(_NativeUnicodeMixin, self).result_processor(dialect, coltype)
+
+class _OracleChar(_NativeUnicodeMixin, sqltypes.CHAR):
def get_dbapi_type(self, dbapi):
return dbapi.FIXED_CHAR
-class _OracleNVarChar(sqltypes.NVARCHAR):
+class _OracleNVarChar(_NativeUnicodeMixin, sqltypes.NVARCHAR):
def get_dbapi_type(self, dbapi):
return dbapi.UNICODE
- def result_processor(self, dialect, coltype):
- if dialect._cx_oracle_native_nvarchar:
- return None
- else:
- return sqltypes.NVARCHAR.result_processor(self, dialect, coltype)
class _OracleText(_LOBMixin, sqltypes.Text):
def get_dbapi_type(self, dbapi):
return dbapi.CLOB
-class _OracleUnicodeText(sqltypes.UnicodeText):
+class _OracleString(_NativeUnicodeMixin, sqltypes.String):
+ pass
+
+class _OracleUnicodeText(_NativeUnicodeMixin, sqltypes.UnicodeText):
def get_dbapi_type(self, dbapi):
return dbapi.NCLOB
sqltypes.Interval : _OracleInterval,
oracle.INTERVAL : _OracleInterval,
sqltypes.Text : _OracleText,
+ sqltypes.String : _OracleString,
sqltypes.UnicodeText : _OracleUnicodeText,
sqltypes.CHAR : _OracleChar,
sqltypes.Integer : _OracleInteger, # this is only needed for OUT parameters.
return impltype(
length=self.length,
convert_unicode=self.convert_unicode,
+ unicode_error=self.unicode_error,
_warn_on_bytestring=True,
)
needs_convert = wants_unicode and \
(dialect.returns_unicode_strings is not True or
self.convert_unicode == 'force')
-
+
if needs_convert:
to_unicode = processors.to_unicode_processor_factory(
dialect.encoding, self.unicode_error)
if bind is None:
bind = _bind_or_error(self)
t = self.dialect_impl(bind.dialect)
- if t is not self:
+ if t is not self and isinstance(t, SchemaType):
t.create(bind=bind, checkfirst=checkfirst)
def drop(self, bind=None, checkfirst=False):
if bind is None:
bind = _bind_or_error(self)
t = self.dialect_impl(bind.dialect)
- if t is not self:
+ if t is not self and isinstance(t, SchemaType):
t.drop(bind=bind, checkfirst=checkfirst)
def _on_table_create(self, event, target, bind, **kw):
t = self.dialect_impl(bind.dialect)
- if t is not self:
+ if t is not self and isinstance(t, SchemaType):
t._on_table_create(event, target, bind, **kw)
def _on_table_drop(self, event, target, bind, **kw):
t = self.dialect_impl(bind.dialect)
- if t is not self:
+ if t is not self and isinstance(t, SchemaType):
t._on_table_drop(event, target, bind, **kw)
def _on_metadata_create(self, event, target, bind, **kw):
t = self.dialect_impl(bind.dialect)
- if t is not self:
+ if t is not self and isinstance(t, SchemaType):
t._on_metadata_create(event, target, bind, **kw)
def _on_metadata_drop(self, event, target, bind, **kw):
t = self.dialect_impl(bind.dialect)
- if t is not self:
+ if t is not self and isinstance(t, SchemaType):
t._on_metadata_drop(event, target, bind, **kw)
class Enum(String, SchemaType):
table.append_constraint(e)
def adapt(self, impltype):
- return impltype(name=self.name,
+ if issubclass(impltype, Enum):
+ return impltype(name=self.name,
quote=self.quote,
schema=self.schema,
metadata=self.metadata,
convert_unicode=self.convert_unicode,
*self.enums
)
+ else:
+ return super(Enum, self).adapt(impltype)
class PickleType(MutableType, TypeDecorator):
"""Holds Python objects.
(Date(), cx_oracle._OracleDate),
(oracle.OracleRaw(), cx_oracle._OracleRaw),
(String(), String),
- (VARCHAR(), VARCHAR),
+ (VARCHAR(), cx_oracle._OracleString),
(DATE(), DATE),
- (String(50), String),
- (Unicode(), Unicode),
+ (String(50), cx_oracle._OracleString),
+ (Unicode(), cx_oracle._OracleNVarChar),
(Text(), cx_oracle._OracleText),
(UnicodeText(), cx_oracle._OracleUnicodeText),
(NCHAR(), cx_oracle._OracleNVarChar),
@testing.emits_warning('.*empty sequence.*')
@testing.fails_on('firebird', "kinterbasdb doesn't send full type information")
@testing.fails_if(lambda:
- (testing.db.name, testing.db.driver) == ('mssql', 'pyodbc')
- and not testing.db.dialect.freetds,
+ testing.against('mssql+pyodbc') and not testing.db.dialect.freetds,
"not supported by Windows ODBC driver")
def test_bind_in(self):
users.insert().execute(user_id = 7, user_name = 'jack')
def test_native_unicode(self):
"""assert expected values for 'native unicode' mode"""
- if testing.against('mssql+pyodbc') and not testing.db.dialect.freetds:
+ if \
+ (testing.against('mssql+pyodbc') and not testing.db.dialect.freetds) or \
+ testing.against('oracle+cx_oracle'):
assert testing.db.dialect.returns_unicode_strings == 'conditional'
return