]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- remove the exclusion of cx_oracle.STRING from setinputsizes by
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 17 Jan 2010 21:12:47 +0000 (21:12 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 17 Jan 2010 21:12:47 +0000 (21:12 +0000)
configuring cx_oracle.UNICODE on OracleNVarChar.  Attempts
were made to pass unicode data to/from a plain VARCHAR2 with
cx_oracle, both with and without setinputsizes in use, but
it doesn't appear to be possible - therefore users will need to use
Unicode/UnicodeText with oracle if data contains non-ASCII info.
[ticket:1517]
- updated the Unicode/UnicodeText docs to reflect this, that
convert_unicode might not be enough.
- allowed convert_unicode='force' to be significant for bind parameters
as well.

lib/sqlalchemy/dialects/oracle/cx_oracle.py
lib/sqlalchemy/types.py
test/sql/test_types.py

index 44344d165b83b6b8094c11122fafe11dfc4350f7..5a94efccb1b6587f30da7536218ffa3f5873ef91 100644 (file)
@@ -118,6 +118,8 @@ class _OracleChar(sqltypes.CHAR):
         return dbapi.FIXED_CHAR
 
 class _OracleNVarChar(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
@@ -204,7 +206,7 @@ class Oracle_cx_oracleExecutionContext(OracleExecutionContext):
                     del param[fromname]
 
         if self.dialect.auto_setinputsizes:
-            self.set_input_sizes(quoted_bind_names, exclude_types=(self.dialect.dbapi.STRING,))
+            self.set_input_sizes(quoted_bind_names)
             
         if len(self.compiled_parameters) == 1:
             for key in self.compiled.binds:
index f2e0481314b8fd36a6da111b851ef6ea537c92dc..47cc37c2db3c3be7537c9a394ae48aefb4004e70 100644 (file)
@@ -478,11 +478,19 @@ class String(Concatenable, TypeEngine):
           If False, may be overridden by
           :attr:`sqlalchemy.engine.base.Dialect.convert_unicode`.
           
-          If the dialect has been detected as returning unicode 
-          strings from a VARCHAR result column, no unicode translation
-          will be done on results.   To force unicode translation
-          for individual types regardless of dialect setting,
-          set convert_unicode='force'.
+          If the DBAPI in use has been detected to return unicode 
+          strings from a VARCHAR result column, the String object will
+          assume all subsequent results are already unicode objects, and no
+          type detection will be done to verify this.  The 
+          rationale here is that isinstance() calls are enormously
+          expensive at the level of column-fetching.  To
+          force the check to occur regardless, set 
+          convert_unicode='force'.
+          
+          Similarly, if the dialect is known to accept bind parameters
+          as unicode objects, no translation from unicode to bytestring
+          is performed on binds.  Again, encoding to a bytestring can be 
+          forced for special circumstances by setting convert_unicode='force'.
 
         :param assert_unicode:
 
@@ -523,7 +531,7 @@ class String(Concatenable, TypeEngine):
                             raise exc.InvalidRequestError("Unicode type received non-unicode bind param value %r" % value)
                     else:
                         return value
-            elif dialect.supports_unicode_binds:
+            elif dialect.supports_unicode_binds and self.convert_unicode != 'force':
                 return None
             else:
                 def process(value):
@@ -583,7 +591,15 @@ class Unicode(String):
     ``u'somevalue'``) into encoded bytestrings when passing the value
     to the database driver, and similarly decodes values from the
     database back into Python ``unicode`` objects.
-
+    
+    It's roughly equivalent to using a ``String`` object with
+    ``convert_unicode=True`` and ``assert_unicode='warn'``, however
+    the type has other significances in that it implies the usage 
+    of a unicode-capable type being used on the backend, such as NVARCHAR.
+    This may affect what type is emitted when issuing CREATE TABLE
+    and also may effect some DBAPI-specific details, such as type
+    information passed along to ``setinputsizes()``.
+    
     When using the ``Unicode`` type, it is only appropriate to pass
     Python ``unicode`` objects, and not plain ``str``.  If a
     bytestring (``str``) is passed, a runtime warning is issued.  If
@@ -626,6 +642,9 @@ class UnicodeText(Text):
     See :class:`Unicode` for details on the unicode
     behavior of this object.
 
+    Like ``Unicode``, usage the ``UnicodeText`` type implies a 
+    unicode-capable type being used on the backend, such as NCLOB.
+
     """
 
     __visit_name__ = 'unicode_text'
index a332dc1bd31b8d7d90dd06e6e5972d4882d66552..065e272759498c8fb2a6262d603c3069af03475f 100644 (file)
@@ -308,8 +308,10 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
         )
 
         x = unicode_table.select().execute().first()
-        self.assert_(isinstance(x['unicode_varchar'], unicode) and x['unicode_varchar'] == unicodedata)
-        self.assert_(isinstance(x['unicode_text'], unicode) and x['unicode_text'] == unicodedata)
+        assert isinstance(x['unicode_varchar'], unicode)
+        eq_(x['unicode_varchar'], unicodedata)
+        assert isinstance(x['unicode_text'], unicode)
+        eq_(x['unicode_text'], unicodedata)
 
     def test_union(self):
         """ensure compiler processing works for UNIONs"""