18 months ago
- object_session() raises the proper
UnmappedInstanceError when presented with an
unmapped instance. [ticket:1881]
1 """
2 Support for the pymssql dialect.
4 This dialect supports pymssql 1.0 and greater.
6 pymssql is available at:
8 http://pymssql.sourceforge.net/
10 Connecting
11 ^^^^^^^^^^
13 Sample connect string::
15 mssql+pymssql://<username>:<password>@<freetds_name>
17 Adding "?charset=utf8" or similar will cause pymssql to return
18 strings as Python unicode objects. This can potentially improve
19 performance in some scenarios as decoding of strings is
20 handled natively.
22 Limitations
23 ^^^^^^^^^^^
25 pymssql inherits a lot of limitations from FreeTDS, including:
27 * no support for multibyte schema identifiers
28 * poor support for large decimals
29 * poor support for binary fields
30 * poor support for VARCHAR/CHAR fields over 255 characters
32 Please consult the pymssql documentation for further information.
34 """
35 from sqlalchemy.dialects.mssql.base import MSDialect
36 from sqlalchemy import types as sqltypes, util, processors
37 import re
38 import decimal
40 class _MSNumeric_pymssql(sqltypes.Numeric):
41 def result_processor(self, dialect, type_):
42 if not self.asdecimal:
43 return processors.to_float
44 else:
45 return sqltypes.Numeric.result_processor(self, dialect, type_)
47 class MSDialect_pymssql(MSDialect):
48 supports_sane_rowcount = False
49 max_identifier_length = 30
50 driver = 'pymssql'
52 colspecs = util.update_copy(
53 MSDialect.colspecs,
54 {
55 sqltypes.Numeric:_MSNumeric_pymssql,
56 sqltypes.Float:sqltypes.Float,
57 }
58 )
59 @classmethod
60 def dbapi(cls):
61 module = __import__('pymssql')
62 # pymmsql doesn't have a Binary method. we use string
63 # TODO: monkeypatching here is less than ideal
64 module.Binary = str
66 client_ver = tuple(int(x) for x in module.__version__.split("."))
67 if client_ver < (1, ):
68 util.warn("The pymssql dialect expects at least "
69 "the 1.0 series of the pymssql DBAPI.")
70 return module
72 def __init__(self, **params):
73 super(MSDialect_pymssql, self).__init__(**params)
74 self.use_scope_identity = True
76 def _get_server_version_info(self, connection):
77 vers = connection.scalar("select @@version")
78 m = re.match(
79 r"Microsoft SQL Server.*? - (\d+).(\d+).(\d+).(\d+)", vers)
80 if m:
81 return tuple(int(x) for x in m.group(1, 2, 3, 4))
82 else:
83 return None
85 def create_connect_args(self, url):
86 opts = url.translate_connect_args(username='user')
87 opts.update(url.query)
88 opts.pop('port', None)
89 return [[], opts]
91 def is_disconnect(self, e):
92 for msg in (
93 "Error 10054",
94 "Not connected to any MS SQL server",
95 "Connection is closed"
96 ):
97 if msg in str(e):
98 return True
99 else:
100 return False
102 dialect = MSDialect_pymssql