Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/sqlalchemy/dialects/mssql/mxodbc.py: 56%
45 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
1# mssql/mxodbc.py
2# Copyright (C) 2005-2022 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: https://www.opensource.org/licenses/mit-license.php
8"""
9.. dialect:: mssql+mxodbc
10 :name: mxODBC
11 :dbapi: mxodbc
12 :connectstring: mssql+mxodbc://<username>:<password>@<dsnname>
13 :url: https://www.egenix.com/
15.. deprecated:: 1.4 The mxODBC DBAPI is deprecated and will be removed
16 in a future version. Please use one of the supported DBAPIs to
17 connect to mssql.
19Execution Modes
20---------------
22mxODBC features two styles of statement execution, using the
23``cursor.execute()`` and ``cursor.executedirect()`` methods (the second being
24an extension to the DBAPI specification). The former makes use of a particular
25API call specific to the SQL Server Native Client ODBC driver known
26SQLDescribeParam, while the latter does not.
28mxODBC apparently only makes repeated use of a single prepared statement
29when SQLDescribeParam is used. The advantage to prepared statement reuse is
30one of performance. The disadvantage is that SQLDescribeParam has a limited
31set of scenarios in which bind parameters are understood, including that they
32cannot be placed within the argument lists of function calls, anywhere outside
33the FROM, or even within subqueries within the FROM clause - making the usage
34of bind parameters within SELECT statements impossible for all but the most
35simplistic statements.
37For this reason, the mxODBC dialect uses the "native" mode by default only for
38INSERT, UPDATE, and DELETE statements, and uses the escaped string mode for
39all other statements.
41This behavior can be controlled via
42:meth:`~sqlalchemy.sql.expression.Executable.execution_options` using the
43``native_odbc_execute`` flag with a value of ``True`` or ``False``, where a
44value of ``True`` will unconditionally use native bind parameters and a value
45of ``False`` will unconditionally use string-escaped parameters.
47"""
50from .base import _MSDate
51from .base import _MSDateTime
52from .base import _MSTime
53from .base import MSDialect
54from .base import VARBINARY
55from .pyodbc import _MSNumeric_pyodbc
56from .pyodbc import MSExecutionContext_pyodbc
57from ... import types as sqltypes
58from ...connectors.mxodbc import MxODBCConnector
61class _MSNumeric_mxodbc(_MSNumeric_pyodbc):
62 """Include pyodbc's numeric processor."""
65class _MSDate_mxodbc(_MSDate):
66 def bind_processor(self, dialect):
67 def process(value):
68 if value is not None:
69 return "%s-%s-%s" % (value.year, value.month, value.day)
70 else:
71 return None
73 return process
76class _MSTime_mxodbc(_MSTime):
77 def bind_processor(self, dialect):
78 def process(value):
79 if value is not None:
80 return "%s:%s:%s" % (value.hour, value.minute, value.second)
81 else:
82 return None
84 return process
87class _VARBINARY_mxodbc(VARBINARY):
89 """
90 mxODBC Support for VARBINARY column types.
92 This handles the special case for null VARBINARY values,
93 which maps None values to the mx.ODBC.Manager.BinaryNull symbol.
94 """
96 def bind_processor(self, dialect):
97 if dialect.dbapi is None:
98 return None
100 DBAPIBinary = dialect.dbapi.Binary
102 def process(value):
103 if value is not None:
104 return DBAPIBinary(value)
105 else:
106 # should pull from mx.ODBC.Manager.BinaryNull
107 return dialect.dbapi.BinaryNull
109 return process
112class MSExecutionContext_mxodbc(MSExecutionContext_pyodbc):
113 """
114 The pyodbc execution context is useful for enabling
115 SELECT SCOPE_IDENTITY in cases where OUTPUT clause
116 does not work (tables with insert triggers).
117 """
119 # todo - investigate whether the pyodbc execution context
120 # is really only being used in cases where OUTPUT
121 # won't work.
124class MSDialect_mxodbc(MxODBCConnector, MSDialect):
126 # this is only needed if "native ODBC" mode is used,
127 # which is now disabled by default.
128 # statement_compiler = MSSQLStrictCompiler
129 supports_statement_cache = True
131 execution_ctx_cls = MSExecutionContext_mxodbc
133 # flag used by _MSNumeric_mxodbc
134 _need_decimal_fix = True
136 colspecs = {
137 sqltypes.Numeric: _MSNumeric_mxodbc,
138 sqltypes.DateTime: _MSDateTime,
139 sqltypes.Date: _MSDate_mxodbc,
140 sqltypes.Time: _MSTime_mxodbc,
141 VARBINARY: _VARBINARY_mxodbc,
142 sqltypes.LargeBinary: _VARBINARY_mxodbc,
143 }
145 def __init__(self, description_encoding=None, **params):
146 super(MSDialect_mxodbc, self).__init__(**params)
147 self.description_encoding = description_encoding
150dialect = MSDialect_mxodbc