From: Mike Bayer Date: Wed, 5 Sep 2012 22:11:33 +0000 (-0400) Subject: - [feature] The types of columns excluded from the X-Git-Tag: rel_0_8_0b1~171 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d3e60f805d573206f68c0eb7e7187c5a1c54a731;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - [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] --- diff --git a/CHANGES b/CHANGES index c81022aa3b..161dd0eb24 100644 --- 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. diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index b6feb426ab..ddd61e5a97 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -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) diff --git a/test/dialect/test_oracle.py b/test/dialect/test_oracle.py index 943cffb48e..55b5bb4ba8 100644 --- a/test/dialect/test_oracle.py +++ b/test/dialect/test_oracle.py @@ -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'