首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django-pyodbc: MSSQL unicode问题

django-pyodbc: MSSQL unicode问题
EN

Stack Overflow用户
提问于 2014-01-31 10:55:07
回答 2查看 2.1K关注 0票数 3

我在使用django-pyodbcfreetdsunixodbc在Django上登录用户时遇到了问题。我可以运行syncdb并与pyodbc连接,没有任何问题。

我得到的全部错误是:

代码语言:javascript
复制
 ('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 conf文件:

代码语言:javascript
复制
[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

odbcinst.ini

代码语言:javascript
复制
[ODBC]
Trace = Yes
TraceFile = /tmp/odbc.log

[FreeTDS]
Description = TDS driver (Sybase/MS SQL)
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup =  /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so
UsageCount = 1
tds_version = 8.0 # several people suggested using underscore

odbc.ini

代码语言:javascript
复制
[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-toolbar's debugsqlshell登录用户,我可以看到这些查询发生在异常之前:

代码语言:javascript
复制
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运行这些查询时,如下所示:

代码语言:javascript
复制
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数据库设置:

代码语言:javascript
复制
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
        },
    }
}

完整回溯:

代码语言:javascript
复制
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)')
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-07 20:43:49

我还建议在选项中包括以下内容,以确保Unicode结果:

代码语言:javascript
复制
'OPTIONS': {
    'host_is_server': True,
    'autocommit': True,
    'unicode_results': True,
    'extra_params': 'tds_version=8.0'
},

Django 1.6也需要自动提交选项。当您以这种方式连接时,它会绕过您可能设置的任何DSN。

编辑: Django的1.6版文件报告“从Django 1.6开始,默认情况下自动提交是打开的”,所以我想您不需要设置这个

票数 6
EN

Stack Overflow用户

发布于 2014-01-31 12:35:33

结果,我还必须在Django数据库设置中指定TDS版本:

代码语言:javascript
复制
'OPTIONS' : { 'host_is_server' : True, 'extra_params' : 'TDS_VERSION=8.0', }

我希望这能帮上忙。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21478295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档