diff options
Diffstat (limited to 'lib/sqlalchemy/dialects/mssql/pyodbc.py')
-rw-r--r-- | lib/sqlalchemy/dialects/mssql/pyodbc.py | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/lib/sqlalchemy/dialects/mssql/pyodbc.py b/lib/sqlalchemy/dialects/mssql/pyodbc.py index 6fd4fc554..60f08a8b3 100644 --- a/lib/sqlalchemy/dialects/mssql/pyodbc.py +++ b/lib/sqlalchemy/dialects/mssql/pyodbc.py @@ -87,7 +87,7 @@ versioning. """ -from .base import MSExecutionContext, MSDialect, VARBINARY +from .base import MSExecutionContext, MSDialect, BINARY, VARBINARY from ...connectors.pyodbc import PyODBCConnector from ... import types as sqltypes, util, exc import decimal @@ -167,7 +167,13 @@ class _MSFloat_pyodbc(_ms_numeric_pyodbc, sqltypes.Float): pass -class _VARBINARY_pyodbc(VARBINARY): +class _ms_binary_pyodbc(object): + """Wraps binary values in dialect-specific Binary wrapper. + If the value is null, return a pyodbc-specific BinaryNull + object to prevent pyODBC [and FreeTDS] from defaulting binary + NULL types to SQLWCHAR and causing implicit conversion errors. + """ + def bind_processor(self, dialect): if dialect.dbapi is None: return None @@ -183,6 +189,14 @@ class _VARBINARY_pyodbc(VARBINARY): return process +class _VARBINARY_pyodbc(_ms_binary_pyodbc, VARBINARY): + pass + + +class _BINARY_pyodbc(_ms_binary_pyodbc, BINARY): + pass + + class MSExecutionContext_pyodbc(MSExecutionContext): _embedded_scope_identity = False @@ -240,7 +254,13 @@ class MSDialect_pyodbc(PyODBCConnector, MSDialect): { sqltypes.Numeric: _MSNumeric_pyodbc, sqltypes.Float: _MSFloat_pyodbc, + BINARY: _BINARY_pyodbc, + + # SQL Server dialect has a VARBINARY that is just to support + # "deprecate_large_types" w/ VARBINARY(max), but also we must + # handle the usual SQL standard VARBINARY VARBINARY: _VARBINARY_pyodbc, + sqltypes.VARBINARY: _VARBINARY_pyodbc, sqltypes.LargeBinary: _VARBINARY_pyodbc, } ) |