diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-05-27 13:02:17 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-05-27 13:02:17 -0400 |
| commit | b086f9a81556250ac6352e092a36e53757f36477 (patch) | |
| tree | e0fa03f1d3e30627917d514a84b32d5fa89feaaa /lib/sqlalchemy | |
| parent | 40c7db67b46fac0029f8caf7a53cbceb05a2324d (diff) | |
| download | sqlalchemy-b086f9a81556250ac6352e092a36e53757f36477.tar.gz | |
- Re-established support for Oracle 8 with cx_oracle,
including that use_ansi is set to False automatically,
NVARCHAR2 and NCLOB are not rendered for Unicode,
"native unicode" check doesn't fail, cx_oracle
"native unicode" mode is disabled, VARCHAR() is emitted
with bytes count instead of char count. [ticket:1808]
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/dialects/oracle/base.py | 56 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/oracle/cx_oracle.py | 8 |
2 files changed, 50 insertions, 14 deletions
diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py index cd232fa00..6443886dc 100644 --- a/lib/sqlalchemy/dialects/oracle/base.py +++ b/lib/sqlalchemy/dialects/oracle/base.py @@ -95,9 +95,21 @@ and specify "passive_updates=False" on each relationship(). Oracle 8 Compatibility ---------------------- -When using Oracle 8, a "use_ansi=False" flag is available which converts all -JOIN phrases into the WHERE clause, and in the case of LEFT OUTER JOIN -makes use of Oracle's (+) operator. +When Oracle 8 is detected, the dialect internally configures itself to the following +behaviors: + +* the use_ansi flag is set to False. This has the effect of converting all + JOIN phrases into the WHERE clause, and in the case of LEFT OUTER JOIN + makes use of Oracle's (+) operator. + +* the NVARCHAR2 and NCLOB datatypes are no longer generated as DDL when + the :class:`~sqlalchemy.types.Unicode` is used - VARCHAR2 and CLOB are issued + instead. This because these types don't seem to work correctly on Oracle 8 + even though they are available. The :class:`~sqlalchemy.types.NVARCHAR` + and :class:`~sqlalchemy.dialects.oracle.NCLOB` types will always generate NVARCHAR2 and NCLOB. + +* the "native unicode" mode is disabled when using cx_oracle, i.e. SQLAlchemy + encodes all Python unicode objects to "string" before passing in as bind parameters. Synonym/DBLINK Reflection ------------------------- @@ -184,9 +196,9 @@ class INTERVAL(sqltypes.TypeEngine): within available DBAPIs (cx_oracle and zxjdbc). :param day_precision: the day precision value. this is the number of digits - to store for the day field. Defaults to "2" + to store for the day field. Defaults to "2" :param second_precision: the second precision value. this is the number of digits - to store for the fractional seconds field. Defaults to "6". + to store for the fractional seconds field. Defaults to "6". """ self.day_precision = day_precision @@ -247,7 +259,10 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler): return self.visit_FLOAT(type_) def visit_unicode(self, type_): - return self.visit_NVARCHAR(type_) + if self.dialect._supports_nchar: + return self.visit_NVARCHAR(type_) + else: + return self.visit_VARCHAR(type_) def visit_INTERVAL(self, type_): return "INTERVAL DAY%s TO SECOND%s" % ( @@ -286,7 +301,7 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler): return "%(name)s(%(precision)s, %(scale)s)" % {'name':name,'precision': precision, 'scale' : scale} def visit_VARCHAR(self, type_): - if self.dialect.supports_char_length: + if self.dialect._supports_char_length: return "VARCHAR(%(length)s CHAR)" % {'length' : type_.length} else: return "VARCHAR(%(length)s)" % {'length' : type_.length} @@ -298,7 +313,10 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler): return self.visit_CLOB(type_) def visit_unicode_text(self, type_): - return self.visit_NCLOB(type_) + if self.dialect._supports_nchar: + return self.visit_NCLOB(type_) + else: + return self.visit_CLOB(type_) def visit_large_binary(self, type_): return self.visit_BLOB(type_) @@ -593,8 +611,6 @@ class OracleDialect(default.DefaultDialect): reflection_options = ('oracle_resolve_synonyms', ) - supports_char_length = True - def __init__(self, use_ansi=True, optimize_limits=False, @@ -608,12 +624,24 @@ class OracleDialect(default.DefaultDialect): self.implicit_returning = self.server_version_info > (10, ) and \ self.__dict__.get('implicit_returning', True) - self.supports_char_length = self.server_version_info >= (9, ) - - if self.server_version_info < (9,): + if self._is_oracle_8: self.colspecs = self.colspecs.copy() self.colspecs.pop(sqltypes.Interval) + self.use_ansi = False + @property + def _is_oracle_8(self): + return self.server_version_info and \ + self.server_version_info < (9, ) + + @util.memoized_property + def _supports_char_length(self): + return not self._is_oracle_8 + + @util.memoized_property + def _supports_nchar(self): + return not self._is_oracle_8 + def do_release_savepoint(self, connection, name): # Oracle does not support RELEASE SAVEPOINT pass @@ -775,7 +803,7 @@ class OracleDialect(default.DefaultDialect): resolve_synonyms, dblink, info_cache=info_cache) columns = [] - if self.supports_char_length: + if self._supports_char_length: char_length_col = 'char_length' else: char_length_col = 'data_length' diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index e82100872..dd32f3201 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -45,6 +45,9 @@ cx_oracle 5 fully supports Python unicode objects. SQLAlchemy will pass all unicode strings directly to cx_oracle, and additionally uses an output handler so that all string based result values are returned as unicode as well. +Note that this behavior is disabled when Oracle 8 is detected, as it has been +observed that issues remain when passing Python unicodes to cx_oracle with Oracle 8. + LOB Objects ----------- @@ -444,6 +447,11 @@ class OracleDialect_cx_oracle(OracleDialect): self.dbapi.BLOB: oracle.BLOB(), self.dbapi.BINARY: oracle.RAW(), } + + def initialize(self, connection): + super(OracleDialect_cx_oracle, self).initialize(connection) + if self._is_oracle_8: + self.supports_unicode_binds = False @classmethod def dbapi(cls): |
