From: Mike Bayer Date: Sun, 18 Sep 2011 19:33:12 +0000 (-0400) Subject: - Changes to attempt support of FreeTDS 0.91 with X-Git-Tag: rel_0_7_3~46 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=57ae8672a6be786c32d79faca90666d5b654bce6;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Changes to attempt support of FreeTDS 0.91 with Pyodbc. This includes that string binds are sent as Python unicode objects when FreeTDS 0.91 is detected, and a CAST(? AS NVARCHAR) is used when we detect for a table. However, I'd continue to characterize Pyodbc + FreeTDS 0.91 behavior as pretty crappy, there are still many queries such as used in reflection which cause a core dump on Linux, and it is not really usable at all on OSX, MemoryErrors abound and just plain broken unicode support. [ticket:2273] --- diff --git a/CHANGES b/CHANGES index 26b7c14287..642fc50c3c 100644 --- a/CHANGES +++ b/CHANGES @@ -156,6 +156,18 @@ CHANGES with the full search_path. [ticket:2249] - mssql + - Changes to attempt support of FreeTDS 0.91 with + Pyodbc. This includes that string binds are sent as + Python unicode objects when FreeTDS 0.91 is detected, + and a CAST(? AS NVARCHAR) is used when we detect + for a table. However, I'd continue + to characterize Pyodbc + FreeTDS 0.91 behavior as + pretty crappy, there are still many queries such + as used in reflection which cause a core dump on + Linux, and it is not really usable at all + on OSX, MemoryErrors abound and just plain broken + unicode support. [ticket:2273] + - "0" is accepted as an argument for limit() which will produce "TOP 0". [ticket:2222] diff --git a/lib/sqlalchemy/connectors/pyodbc.py b/lib/sqlalchemy/connectors/pyodbc.py index ea4810df7a..562cf92735 100644 --- a/lib/sqlalchemy/connectors/pyodbc.py +++ b/lib/sqlalchemy/connectors/pyodbc.py @@ -29,6 +29,10 @@ class PyODBCConnector(Connector): # if the freetds.so is detected freetds = False + # will be set to the string version of + # the FreeTDS driver if freetds is detected + freetds_driver_version = None + # will be set to True after initialize() # if the libessqlsrv.so is detected easysoft = False @@ -108,11 +112,15 @@ class PyODBCConnector(Connector): self.easysoft = bool(re.match(r".*libessqlsrv.*\.so", _sql_driver_name )) + if self.freetds: + self.freetds_driver_version = dbapi_con.getinfo(pyodbc.SQL_DRIVER_VER) + # the "Py2K only" part here is theoretical. # have not tried pyodbc + python3.1 yet. # Py2K self.supports_unicode_statements = not self.freetds and not self.easysoft - self.supports_unicode_binds = not self.freetds and not self.easysoft + self.supports_unicode_binds = (not self.freetds or + self.freetds_driver_version >= '0.91') and not self.easysoft # end Py2K # run other initialization which asks for user name, etc. diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 015c346eb1..981ffc2384 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -171,7 +171,7 @@ import datetime, operator, re from sqlalchemy import sql, schema as sa_schema, exc, util from sqlalchemy.sql import select, compiler, expression, \ operators as sql_operators, \ - util as sql_util + util as sql_util, cast from sqlalchemy.engine import default, base, reflection from sqlalchemy import types as sqltypes from sqlalchemy.types import INTEGER, BIGINT, SMALLINT, DECIMAL, NUMERIC, \ @@ -1135,11 +1135,10 @@ class MSDialect(default.DefaultDialect): def has_table(self, connection, tablename, schema=None): current_schema = schema or self.default_schema_name columns = ischema.columns + whereclause = cast(columns.c.table_name, NVARCHAR(_warn_on_bytestring=False))==tablename if current_schema: - whereclause = sql.and_(columns.c.table_name==tablename, + whereclause = sql.and_(whereclause, columns.c.table_schema==current_schema) - else: - whereclause = columns.c.table_name==tablename s = sql.select([columns], whereclause) c = connection.execute(s) return c.first() is not None