Sql server django pyodbc:MSSQL unicode问题
使用Sql server django pyodbc:MSSQL unicode问题,sql-server,django,odbc,freetds,django-pyodbc,Sql Server,Django,Odbc,Freetds,Django Pyodbc,使用Django-pyodbc、freetds和unixodbc在Django上登录用户时遇到问题。我可以毫无问题地运行syncdb并连接pyodbc 我得到的全部错误是: ('42000', '[42000] [FreeTDS][SQL Server]Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC v
Django-pyodbc
、freetds
和unixodbc
在Django上登录用户时遇到问题。我可以毫无问题地运行syncdb
并连接pyodbc
我得到的全部错误是:
('42000', '[42000] [FreeTDS][SQL Server]Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier. (4004) (SQLExecDirectW)
freetds配置文件:
[PS123]
host = <ip number>
port = 2254
tds version = 8.0
instance = T_INS01
client charset = UTF-8
# somebody suggested this had to be global so I put it here as well
[global]
client charset = UTF-8
tds version = 8.0
odbc.ini
[PS123]
Driver = FreeTDS
Description = A wonderful description goes here
tds_version = 8.0 # also tried without underscore here
Database = database
Servername = PS123
Trace = Yes
TraceFile = /tmp/freetdssql.log
如果我通过django debug工具栏的debugsqlshell登录用户,我可以看到异常之前发生的查询:
In [10]: login(request, user)
SELECT TOP 1 (1) AS [a] FROM [django_session] WHERE [django_session].[session_key] = magyul563p13z6e33t6rexesaxx1kszx [5.03ms]
INSERT INTO [django_session] ([session_key], [session_data], [expire_date])
VALUES (magyul563p13z6e33t6rexesaxx1kszx,
ZjgwN2E1NGZhNTE4YTI2ZWQxMDM3M2ZlZThiNWVlY2NlYTlmZWQ1YzqAAn1xAS4=, 2014-02-14 10:20:31+00:00) [3.23ms]
SELECT [django_session].[session_key], [django_session].[session_data], [django_session].[expire_date] FROM [django_session] WHERE [django_session].[session_key] = magyul563p13z6e33t6rexesaxx1kszx [1.56ms]
但当我仅使用pyodbc
运行这些查询时,如下所示:
import pyodbc
cnx = pyodbc.connect("DSN=PS123;UID=username;PWD=password")
cursor = cnx.cursor()
cursor.execute("SELECT TOP 1 (1) AS [a] FROM [django_session] WHERE [django_session].[session_key] = 'azozj51b9a5y9lnbq2b4hydhrryrplpz'")
cursor.execute("INSERT INTO [django_session] ([session_key], [session_data], [expire_date]) VALUES ('azozj51b9a5y9lnbq2b4hyd', 'ZwN2E1NGZhNTE4YTI2ZWQxMDM3M2ZlZThiNWVlY2NlYTlmZWQ1YzqAAn1x', '2014-02-15')")
cursor.execute("SELECT [django_session].[session_key], [django_session].[session_data], [django_session].[expire_date] FROM [django_session] WHERE [django_session].[session_key] = 'azozj51b9a5y9lnbq2b4hyd'")
它获取和插入没有任何问题。唯一的问题是我必须删除日期字符串中的时间和时区。我认为这与我的问题无关
以下是我的Django数据库设置:
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc', # also tried django_pyodbc
'NAME': 'database',
'USER': 'username',
'PASSWORD': 'password',
'HOST': 'PS123',
'PORT': '2254',
'OPTIONS': {
'host_is_server': True
},
}
}
完全回溯:
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in wrapper
219. return self.admin_view(view, cacheable)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
89. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in inner
196. if not self.has_permission(request):
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in has_permission
149. return request.user.is_active and request.user.is_staff
File "/usr/local/lib/python2.7/dist-packages/django/utils/functional.py" in inner
204. self._setup()
File "/usr/local/lib/python2.7/dist-packages/django/utils/functional.py" in _setup
270. self._wrapped = self._setupfunc()
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/middleware.py" in <lambda>
18. request.user = SimpleLazyObject(lambda: get_user(request))
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/middleware.py" in get_user
10. request._cached_user = auth.get_user(request)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/__init__.py" in get_user
136. user_id = request.session[SESSION_KEY]
File "/usr/local/lib/python2.7/dist-packages/django/contrib/sessions/backends/base.py" in __getitem__
44. return self._session[key]
File "/usr/local/lib/python2.7/dist-packages/django/contrib/sessions/backends/base.py" in _get_session
167. self._session_cache = self.load()
File "/usr/local/lib/python2.7/dist-packages/django/contrib/sessions/backends/db.py" in load
18. expire_date__gt=timezone.now()
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py" in get
143. return self.get_query_set().get(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in get
398. num = len(clone)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in __len__
106. self._result_cache = list(self.iterator())
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in iterator
317. for row in compiler.results_iter():
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py" in results_iter
775. for rows in self.execute_sql(MULTI):
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py" in execute_sql
846. cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/util.py" in execute
41. return self.cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/sql_server/pyodbc/base.py" in execute
396. raise utils.DatabaseError(*e.args)
Exception Type: DatabaseError at /admin/
Exception Value: ('42000', '[42000] [FreeTDS][SQL Server]Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier. (4004) (SQLExecDirectW)')
回溯:
get_响应中的文件“/usr/local/lib/python2.7/dist packages/django/core/handlers/base.py”
115响应=回调(请求,*回调参数,**回调参数)
包装器中的文件“/usr/local/lib/python2.7/dist packages/django/contrib/admin/sites.py”
219返回self.admin_视图(视图,可缓存)(*args,**kwargs)
视图中的文件“/usr/local/lib/python2.7/dist packages/django/utils/decorators.py”
91响应=查看功能(请求,*args,**kwargs)
文件“/usr/local/lib/python2.7/dist packages/django/views/decorators/cache.py”
89响应=查看功能(请求,*args,**kwargs)
文件“/usr/local/lib/python2.7/dist packages/django/contrib/admin/sites.py”
196如果不是self.has_权限(请求):
中的文件“/usr/local/lib/python2.7/dist packages/django/contrib/admin/sites.py”具有\u权限
149return request.user.is_活动,request.user.is_工作人员
文件“/usr/local/lib/python2.7/dist packages/django/utils/functional.py”
204self.\u设置()
安装程序中的文件“/usr/local/lib/python2.7/dist-packages/django/utils/functional.py”
270self.\u wrapped=self.\u setupfunc()
文件“/usr/local/lib/python2.7/dist packages/django/contrib/auth/middleware.py”
18request.user=SimpleLazyObject(lambda:get_user(request))
get_user中的文件“/usr/local/lib/python2.7/dist packages/django/contrib/auth/middleware.py”
10请求。_cached_user=auth.get_user(请求)
get\U user中的文件“/usr/local/lib/python2.7/dist packages/django/contrib/auth/\uuu init\uu.py”
136user\u id=request.session[session\u KEY]
文件“/usr/local/lib/python2.7/dist packages/django/contrib/sessions/backends/base.py”__
44返回self.\u会话[键]
文件“/usr/local/lib/python2.7/dist packages/django/contrib/sessions/backends/base.py”位于get会话中
167self.\u session\u cache=self.load()
加载文件“/usr/local/lib/python2.7/dist-packages/django/contrib/sessions/backends/db.py”
18expire\u date\uu gt=timezone.now()
get中的文件“/usr/local/lib/python2.7/dist packages/django/db/models/manager.py”
143返回self.get\u query\u set().get(*args,**kwargs)
get中的文件“/usr/local/lib/python2.7/dist packages/django/db/models/query.py”
398num=len(克隆)
文件“/usr/local/lib/python2.7/dist packages/django/db/models/query.py”__
106self.\u result\u cache=list(self.iterator())
迭代器中的文件“/usr/local/lib/python2.7/dist packages/django/db/models/query.py”
317对于编译器.results\u iter()中的行:
结果文件中的文件“/usr/local/lib/python2.7/dist packages/django/db/models/sql/compiler.py”
775对于self.execute_sql(多)中的行:
execute_sql中的文件“/usr/local/lib/python2.7/dist packages/django/db/models/sql/compiler.py”
846cursor.execute(sql,params)
execute中的文件“/usr/local/lib/python2.7/dist packages/django/db/backends/util.py”
41返回self.cursor.execute(sql,params)
execute中的文件“/usr/local/lib/python2.7/dist packages/sql\u server/pyodbc/base.py”
396raise utils.DatabaseError(*e.args)
异常类型:数据库错误位于/admin/
异常值:('42000'、'[42000][FreeTDS][SQL Server]纯Unicode排序规则中的Unicode数据或ntext数据不能发送到使用DB库(如ISQL)或ODBC版本3.7或更早版本的客户端。(4004)(SQLExecDirectW))
事实证明,我还必须在Django数据库设置中指定TDS版本:
'OPTIONS' : { 'host_is_server' : True, 'extra_params' : 'TDS_VERSION=8.0', }
我希望这对某些人有所帮助。我还建议在选项中包括以下内容,以确保Unicode结果:
'OPTIONS': {
'host_is_server': True,
'autocommit': True,
'unicode_results': True,
'extra_params': 'tds_version=8.0'
},
Django 1.6还需要自动提交选项。以这种方式连接时,它会绕过您可能已设置的任何DSN
编辑:报告“自Django 1.6以来,自动提交在默认情况下处于打开状态”,因此我想您不需要设置此最佳答案,它修复了我在SQL server 2012与Django 1.7、freetds和pyodbc连接时的字符编码问题。我们应该接受这个答案!自从我最初的回答之后,我了解到了更多的信息,这只是一个评论:虽然“TDS_VERSION=8.0”可以工作,但微软已经发布了一个官方版本编号,以符合其TDS规范。虽然两者都可以工作,但正确的版本是“TDS_version=7.2”。
'OPTIONS': {
'host_is_server': True,
'autocommit': True,
'unicode_results': True,
'extra_params': 'tds_version=8.0'
},