]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [feature] The types of columns excluded from the
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 5 Sep 2012 22:11:33 +0000 (18:11 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 5 Sep 2012 22:11:33 +0000 (18:11 -0400)
    setinputsizes() set can be customized by sending
    a list of string DBAPI type names to exclude.
   This list was previously fixed.  The list also
    now defaults to STRING, UNICODE, removing
    CLOB, NCLOB from the list.  [ticket:2469]

CHANGES
lib/sqlalchemy/dialects/oracle/cx_oracle.py
test/dialect/test_oracle.py

diff --git a/CHANGES b/CHANGES
index c81022aa3b4d83f7e6069d1a6dd9bd9153619b35..161dd0eb241742aaadf9c583fc10c964b88ab2d0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -629,6 +629,13 @@ underneath "0.7.xx".
     statements, so that unknown reserved names can
     be fully supported.  [ticket:2437]
 
+  - [feature] The types of columns excluded from the
+    setinputsizes() set can be customized by sending
+    a list of string DBAPI type names to exclude.
+    This list was previously fixed.  The list also
+    now defaults to STRING, UNICODE, removing
+    CLOB, NCLOB from the list.  [ticket:2469]
+
 - extensions
   - [removed] The SQLSoup extension is removed from
     SQLAlchemy, and is now an external project.
index b6feb426ab8a7910a57d7f5b97277bc605b885bb..ddd61e5a97ef6421ab33be4a633cfac637a90ffe 100644 (file)
@@ -20,29 +20,43 @@ Connecting
 ----------
 
 Connecting with create_engine() uses the standard URL approach of
-``oracle://user:pass@host:port/dbname[?key=value&key=value...]``.  If dbname is present, the
-host, port, and dbname tokens are converted to a TNS name using the cx_oracle
-:func:`makedsn()` function.  Otherwise, the host token is taken directly as a TNS name.
+``oracle://user:pass@host:port/dbname[?key=value&key=value...]``.  If dbname is
+present, the host, port, and dbname tokens are converted to a TNS name using
+the cx_oracle :func:`makedsn()` function.  Otherwise, the host token is taken
+directly as a TNS name.
 
-Additional arguments which may be specified either as query string arguments on the
-URL, or as keyword arguments to :func:`~sqlalchemy.create_engine()` are:
+Additional arguments which may be specified either as query string arguments
+on the URL, or as keyword arguments to :func:`~sqlalchemy.create_engine()` are:
 
-* *allow_twophase* - enable two-phase transactions.  Defaults to ``True``.
+* allow_twophase - enable two-phase transactions.  Defaults to ``True``.
 
-* *arraysize* - set the cx_oracle.arraysize value on cursors, in SQLAlchemy
+* arraysize - set the cx_oracle.arraysize value on cursors, in SQLAlchemy
   it defaults to 50.  See the section on "LOB Objects" below.
 
-* *auto_convert_lobs* - defaults to True, see the section on LOB objects.
+* auto_convert_lobs - defaults to True, see the section on LOB objects.
 
-* *auto_setinputsizes* - the cx_oracle.setinputsizes() call is issued for all bind parameters.
-  This is required for LOB datatypes but can be disabled to reduce overhead.  Defaults
-  to ``True``.
+* auto_setinputsizes - the cx_oracle.setinputsizes() call is issued for
+  all bind parameters.  This is required for LOB datatypes but can be
+  disabled to reduce overhead.  Defaults to ``True``.  Specific types
+  can be excluded from this process using the ``exclude_setinputsizes``
+  parameter.
 
-* *mode* - This is given the string value of SYSDBA or SYSOPER, or alternatively an
-  integer value.  This value is only available as a URL query string argument.
+* exclude_setinputsizes - a tuple or list of string DBAPI type names to
+  be excluded from the "auto setinputsizes" feature.  The type names here
+  must match DBAPI types that are found in the "cx_Oracle" module namespace,
+  such as cx_Oracle.UNICODE, cx_Oracle.NCLOB, etc.   Defaults to
+  ``(STRING, UNICODE)``.
 
-* *threaded* - enable multithreaded access to cx_oracle connections.  Defaults
-  to ``True``.  Note that this is the opposite default of cx_oracle itself.
+  .. versionadded:: 0.8 specific DBAPI types can be excluded from the
+     auto_setinputsizes feature via the exclude_setinputsizes attribute.
+
+* mode - This is given the string value of SYSDBA or SYSOPER, or alternatively
+  an integer value.  This value is only available as a URL query string
+  argument.
+
+* threaded - enable multithreaded access to cx_oracle connections.  Defaults
+  to ``True``.  Note that this is the opposite default of the cx_Oracle DBAPI
+  itself.
 
 Unicode
 -------
@@ -338,7 +352,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext):
             # on String, including that outparams/RETURNING
             # breaks for varchars
             self.set_input_sizes(quoted_bind_names,
-                                 exclude_types=self.dialect._cx_oracle_string_types
+                                 exclude_types=self.dialect.exclude_setinputsizes
                                 )
 
         # if a single execute, check for outparams
@@ -483,6 +497,7 @@ class OracleDialect_cx_oracle(OracleDialect):
 
     def __init__(self,
                 auto_setinputsizes=True,
+                exclude_setinputsizes=("STRING", "UNICODE"),
                 auto_convert_lobs=True,
                 threaded=True,
                 allow_twophase=True,
@@ -492,21 +507,25 @@ class OracleDialect_cx_oracle(OracleDialect):
         self.threaded = threaded
         self.arraysize = arraysize
         self.allow_twophase = allow_twophase
-        self.supports_timestamp = self.dbapi is None or hasattr(self.dbapi, 'TIMESTAMP' )
+        self.supports_timestamp = self.dbapi is None or \
+                                        hasattr(self.dbapi, 'TIMESTAMP')
         self.auto_setinputsizes = auto_setinputsizes
         self.auto_convert_lobs = auto_convert_lobs
 
         if hasattr(self.dbapi, 'version'):
-            self.cx_oracle_ver = tuple([int(x) for x in self.dbapi.version.split('.')])
+            self.cx_oracle_ver = tuple([int(x) for x in
+                                self.dbapi.version.split('.')])
         else:
             self.cx_oracle_ver = (0, 0, 0)
 
         def types(*names):
-            return set([
-                        getattr(self.dbapi, name, None) for name in names
-                    ]).difference([None])
+            return set(
+                    getattr(self.dbapi, name, None) for name in names
+                    ).difference([None])
 
-        self._cx_oracle_string_types = types("STRING", "UNICODE", "NCLOB", "CLOB")
+        self.exclude_setinputsizes = types(*(exclude_setinputsizes or ()))
+        self._cx_oracle_string_types = types("STRING", "UNICODE",
+                                            "NCLOB", "CLOB")
         self._cx_oracle_unicode_types = types("UNICODE", "NCLOB")
         self._cx_oracle_binary_types = types("BFILE", "CLOB", "NCLOB", "BLOB")
         self.supports_unicode_binds = self.cx_oracle_ver >= (5, 0)
index 943cffb48e3f50aad52c9ee7620625f4fce76f46..55b5bb4ba8da8a416087e93e86a8241c29a4d0b6 100644 (file)
@@ -47,6 +47,26 @@ create or replace procedure foo(x_in IN number, x_out OUT number, y_out OUT numb
     def teardown_class(cls):
          testing.db.execute("DROP PROCEDURE foo")
 
+class CXOracleArgsTest(fixtures.TestBase):
+    __only_on__ = 'oracle+cx_oracle'
+
+    def test_autosetinputsizes(self):
+        dialect = cx_oracle.dialect()
+        assert dialect.auto_setinputsizes
+
+        dialect = cx_oracle.dialect(auto_setinputsizes=False)
+        assert not dialect.auto_setinputsizes
+
+    def test_exclude_inputsizes_none(self):
+        dialect = cx_oracle.dialect(exclude_setinputsizes=None)
+        eq_(dialect.exclude_setinputsizes, set())
+
+    def test_exclude_inputsizes_custom(self):
+        import cx_Oracle
+        dialect = cx_oracle.dialect(dbapi=cx_Oracle,
+                            exclude_setinputsizes=('NCLOB',))
+        eq_(dialect.exclude_setinputsizes, set([cx_Oracle.NCLOB]))
+
 class QuotedBindRoundTripTest(fixtures.TestBase):
 
     __only_on__ = 'oracle'