Improve Unicode support for MSSQL (#6690)

* Implement unicode where cluases for mssql queries

* Add comment about unicode support on sqla 1.3+
This commit is contained in:
Ville Brofeldt 2019-01-29 08:56:46 +02:00 committed by Maxime Beauchemin
parent c4fb7a0a87
commit c44ae612df
3 changed files with 24 additions and 1 deletions

View File

@ -405,6 +405,11 @@ You can also use `PyAthena` library(no java required) like this ::
See `PyAthena <https://github.com/laughingman7743/PyAthena#sqlalchemy>`_.
MSSQL
-----
Full Unicode support requires SQLAlchemy 1.3 or later.
Snowflake
---------

View File

@ -115,7 +115,9 @@ class TableColumn(Model, BaseColumn):
label = label if label else self.column_name
label = self.table.get_label(label)
if not self.expression:
col = column(self.column_name).label(label)
db_engine_spec = self.table.database.db_engine_spec
type_ = db_engine_spec.get_sqla_column_type(self.type)
col = column(self.column_name, type_=type_).label(label)
else:
col = literal_column(self.expression).label(label)
return col

View File

@ -46,6 +46,7 @@ from sqlalchemy.engine import create_engine
from sqlalchemy.engine.url import make_url
from sqlalchemy.sql import quoted_name, text
from sqlalchemy.sql.expression import TextAsFrom
from sqlalchemy.types import UnicodeText
import sqlparse
from werkzeug.utils import secure_filename
@ -400,6 +401,15 @@ class BaseEngineSpec(object):
label = cls.mutate_label(label)
return quoted_name(label, True) if cls.force_column_alias_quotes else label
@classmethod
def get_sqla_column_type(cls, type_):
"""
Return a sqlalchemy native column type that corresponds to the column type
defined in the data source (optional). Needs to be overridden if column requires
special handling (see MSSQL for example of NCHAR/NVARCHAR handling).
"""
return None
@staticmethod
def mutate_label(label):
"""
@ -1362,6 +1372,12 @@ class MssqlEngineSpec(BaseEngineSpec):
data = [[elem for elem in r] for r in data]
return data
@classmethod
def get_sqla_column_type(cls, type_):
if isinstance(type_, str) and re.match(r'^N(VAR){0-1}CHAR', type_):
return UnicodeText()
return None
class AthenaEngineSpec(BaseEngineSpec):
engine = 'awsathena'