From: Mike Bayer Date: Sat, 24 Sep 2011 15:02:29 +0000 (-0400) Subject: - The String type now generates VARCHAR2 on Oracle X-Git-Tag: rel_0_7_3~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f347edd14cf9ab1b01c7570a65228d964d2b4a6;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - The String type now generates VARCHAR2 on Oracle which is recommended as the default VARCHAR. Added an explicit VARCHAR2 and NVARCHAR2 to the Oracle dialect as well. Using NVARCHAR still generates "NVARCHAR2" - there is no "NVARCHAR" on Oracle - this remains a slight breakage of the "uppercase types always give exactly that" policy. VARCHAR still generates "VARCHAR", keeping with the policy. If Oracle were to ever define "VARCHAR" as something different as they claim (IMHO this will never happen), the type would be available. [ticket:2252] --- diff --git a/CHANGES b/CHANGES index d3a5e4a33f..7b5b76089c 100644 --- a/CHANGES +++ b/CHANGES @@ -238,6 +238,18 @@ CHANGES - Fixed ReturningResultProxy for zxjdbc dialect. [ticket:2272]. Regression from 0.6. + - The String type now generates VARCHAR2 on Oracle + which is recommended as the default VARCHAR. + Added an explicit VARCHAR2 and NVARCHAR2 to the Oracle + dialect as well. Using NVARCHAR still generates + "NVARCHAR2" - there is no "NVARCHAR" on Oracle - + this remains a slight breakage of the "uppercase types + always give exactly that" policy. VARCHAR still + generates "VARCHAR", keeping with the policy. If + Oracle were to ever define "VARCHAR" as something + different as they claim (IMHO this will never happen), + the type would be available. [ticket:2252] + - ext - Added local_attr, remote_attr, attr accessors to AssociationProxy, providing quick access diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py index ff70208517..91be5a95d1 100644 --- a/lib/sqlalchemy/dialects/oracle/base.py +++ b/lib/sqlalchemy/dialects/oracle/base.py @@ -170,7 +170,9 @@ OracleRaw = RAW class NCLOB(sqltypes.Text): __visit_name__ = 'NCLOB' -VARCHAR2 = VARCHAR +class VARCHAR2(VARCHAR): + __visit_name__ = 'VARCHAR2' + NVARCHAR2 = NVARCHAR class NUMBER(sqltypes.Numeric, sqltypes.Integer): @@ -293,9 +295,9 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler): def visit_unicode(self, type_): if self.dialect._supports_nchar: - return self.visit_NVARCHAR(type_) + return self.visit_NVARCHAR2(type_) else: - return self.visit_VARCHAR(type_) + return self.visit_VARCHAR2(type_) def visit_INTERVAL(self, type_): return "INTERVAL DAY%s TO SECOND%s" % ( @@ -333,14 +335,27 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler): else: return "%(name)s(%(precision)s, %(scale)s)" % {'name':name,'precision': precision, 'scale' : scale} + def visit_string(self, type_): + return self.visit_VARCHAR2(type_) + + def visit_VARCHAR2(self, type_): + return self._visit_varchar(type_, '', '2') + + def visit_NVARCHAR2(self, type_): + return self._visit_varchar(type_, 'N', '2') + visit_NVARCHAR = visit_NVARCHAR2 + def visit_VARCHAR(self, type_): - if self.dialect._supports_char_length: - return "VARCHAR(%(length)s CHAR)" % {'length' : type_.length} - else: - return "VARCHAR(%(length)s)" % {'length' : type_.length} + return self._visit_varchar(type_, '', '') - def visit_NVARCHAR(self, type_): - return "NVARCHAR2(%(length)s)" % {'length' : type_.length} + def _visit_varchar(self, type_, n, num): + if not n and self.dialect._supports_char_length: + return "VARCHAR%(two)s(%(length)s CHAR)" % { + 'length' : type_.length, + 'two':num} + else: + return "%(n)sVARCHAR%(two)s(%(length)s)" % {'length' : type_.length, + 'two':num, 'n':n} def visit_text(self, type_): return self.visit_CLOB(type_) diff --git a/test/dialect/test_oracle.py b/test/dialect/test_oracle.py index 4b53500b35..f12b355932 100644 --- a/test/dialect/test_oracle.py +++ b/test/dialect/test_oracle.py @@ -436,8 +436,8 @@ class CompatFlagsTest(fixtures.TestBase, AssertsCompiledSQL): assert not dialect._supports_char_length assert not dialect._supports_nchar assert not dialect.use_ansi - self.assert_compile(String(50),"VARCHAR(50)",dialect=dialect) - self.assert_compile(Unicode(50),"VARCHAR(50)",dialect=dialect) + self.assert_compile(String(50),"VARCHAR2(50)",dialect=dialect) + self.assert_compile(Unicode(50),"VARCHAR2(50)",dialect=dialect) self.assert_compile(UnicodeText(),"CLOB",dialect=dialect) dialect = oracle.dialect(implicit_returning=True, @@ -454,7 +454,7 @@ class CompatFlagsTest(fixtures.TestBase, AssertsCompiledSQL): assert dialect._supports_char_length assert dialect._supports_nchar assert dialect.use_ansi - self.assert_compile(String(50),"VARCHAR(50 CHAR)",dialect=dialect) + self.assert_compile(String(50),"VARCHAR2(50 CHAR)",dialect=dialect) self.assert_compile(Unicode(50),"NVARCHAR2(50)",dialect=dialect) self.assert_compile(UnicodeText(),"NCLOB",dialect=dialect) @@ -467,7 +467,7 @@ class CompatFlagsTest(fixtures.TestBase, AssertsCompiledSQL): assert dialect._supports_char_length assert dialect._supports_nchar assert dialect.use_ansi - self.assert_compile(String(50),"VARCHAR(50 CHAR)",dialect=dialect) + self.assert_compile(String(50),"VARCHAR2(50 CHAR)",dialect=dialect) self.assert_compile(Unicode(50),"NVARCHAR2(50)",dialect=dialect) self.assert_compile(UnicodeText(),"NCLOB",dialect=dialect) @@ -1086,7 +1086,19 @@ class TypesTest(fixtures.TestBase, AssertsCompiledSQL): eq_(t2.c.c3.type.length, 200) finally: t1.drop() - + + def test_varchar_types(self): + dialect = oracle.dialect() + for typ, exp in [ + (String(50), "VARCHAR2(50 CHAR)"), + (Unicode(50), "NVARCHAR2(50)"), + (NVARCHAR(50), "NVARCHAR2(50)"), + (VARCHAR(50), "VARCHAR(50 CHAR)"), + (oracle.NVARCHAR2(50), "NVARCHAR2(50)"), + (oracle.VARCHAR2(50), "VARCHAR2(50 CHAR)"), + ]: + self.assert_compile(typ, exp, dialect=dialect) + def test_longstring(self): metadata = MetaData(testing.db) testing.db.execute("""