2014-01-22 65 views
3

我試圖將在IIS 7上遠程運行的SQL Server 2008 R2數據庫同步到使用manage.py syncdb在Windows 7上運行python 3.3的django 1.6應用程序。但是我被會見了錯誤,無法使用Django-pyodbc從django查詢SQL Server

TypeError: The first argument to execute must be a string or unicode query. 

我有Django的pyodbc 0.2.3和3.0.7 pyodbc安裝,與我的settings.py DATABASES如,

{ 
    'default': { 
    'ENGINE': 'django_pyodbc', 
    'HOST': '...', 
    'NAME': '...', 
    'OPTIONS': { 
     'host_is_server': True 
    } 
    } 
} 

正如你可能猜測,USERPASSWORD被省略,因爲我需要Integrated_Security=YesTrusted_Connection=Yes進行連接。由於django-pyodbc初始化類DatabaseWrapper,即使host_is_server在Windows上不相關,OPTIONS似乎必須是非空的。

我收到完整的錯誤是:

Traceback (most recent call last): 
    File "Z:\python\ns_reports_server\manage.py", line 10, in <module> 
    execute_from_command_line(sys.argv) 
    File "C:\Python33\lib\site-packages\django-1.6.1-py3.3.egg\django\core\management\__init__.py", line 399, in execute_from_command_line 
    utility.execute() 
    File "C:\Python33\lib\site-packages\django-1.6.1-py3.3.egg\django\core\management\__init__.py", line 392, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "C:\Python33\lib\site-packages\django-1.6.1-py3.3.egg\django\core\management\base.py", line 242, in run_from_argv 
    self.execute(*args, **options.__dict__) 
    File "C:\Python33\lib\site-packages\django-1.6.1-py3.3.egg\django\core\management\base.py", line 285, in execute 
    output = self.handle(*args, **options) 
    File "C:\Python33\lib\site-packages\django-1.6.1-py3.3.egg\django\core\management\base.py", line 415, in handle 
    return self.handle_noargs(**options) 
    File "C:\Python33\lib\site-packages\django-1.6.1-py3.3.egg\django\core\management\commands\syncdb.py", line 57, in handle_noargs 
    cursor = connection.cursor() 
    File "C:\Python33\lib\site-packages\django-1.6.1-py3.3.egg\django\db\backends\__init__.py", line 157, in cursor 
    cursor = self.make_debug_cursor(self._cursor()) 
    File "C:\Python33\lib\site-packages\django_pyodbc-0.2.3-py3.3.egg\django_pyodbc\base.py", line 290, in _cursor 
    File "C:\Python33\lib\site-packages\django_pyodbc-0.2.3-py3.3.egg\django_pyodbc\operations.py", line 31, in _get_sql_server_ver 
    File "C:\Python33\lib\site-packages\django-1.6.1-py3.3.egg\django\db\backends\util.py", line 69, in execute 
    return super(CursorDebugWrapper, self).execute(sql, params) 
    File "C:\Python33\lib\site-packages\django-1.6.1-py3.3.egg\django\db\backends\util.py", line 51, in execute 
    return self.cursor.execute(sql) 
    File "C:\Python33\lib\site-packages\django_pyodbc-0.2.3-py3.3.egg\django_pyodbc\base.py", line 410, in execute 
TypeError: The first argument to execute must be a string or unicode query. 

如果你看一下從頂部的第十個呼叫的源代碼,django_pyodbc/operations.py被查詢的SQL Server版本的連接,

cur.execute("SELECT CAST(SERVERPROPERTY('ProductVersion') as varchar)") 

然而,在調用堆棧的最後,這個要執行的sql已經消失。 django_pyodbc/base.py具有

return self.cursor.execute(sql, params) 

的量,第一個參數沒有被識別爲「字串或Unicode查詢」。

Python,django和SQL Server對我來說都是新的,所以答案可能很明顯,但我不能在我的生活中解決它。乾杯。

回答

2

編輯:driver_supports_utf8 =如其他答案中提到的將是正確的修復。

看起來這與Django的pyodbc和Python問題3.

在base.py,線367是

sql = sql.encode('utf-8') 

此行變成一個字符串轉換爲字節,這是什麼原因造成的類型錯誤。由於你在Windows上是 ,我假設驅動程序可以處理unicode。我建議你註釋第364至367行(format_sql函數的前4個)。這樣你的unicode字符串將保持unicode,你將不會得到TypeError。

https://github.com/lionheart/django-pyodbc/blob/master/django_pyodbc/base.py

def format_sql(self, sql, n_params=None): 
    if not self.driver_supports_utf8 and isinstance(sql, text_type): 
     # Older FreeTDS (and other ODBC drivers?) don't support Unicode yet, so 
     # we need to encode the SQL clause itself in utf-8 
     sql = sql.encode('utf-8') 
    # pyodbc uses '?' instead of '%s' as parameter placeholder. 
    if n_params is not None: 
     try: 
      sql = sql % tuple('?' * n_params) 
     except: 
      #Todo checkout whats happening here 
      pass 
    else: 
     if '%s' in sql: 
      sql = sql.replace('%s', '?') 
    return sql 

我已經提出了與Django的pyodbc其進入更詳細一點的問題。

https://github.com/lionheart/django-pyodbc/issues/47

2

你也可以在你的配置選項解決這個問題。我與此戰鬥了一段時間。試着改變你的DB這樣被config'd 1.6:

DATABASES = { 
    'default': { 
     'ENGINE': 'django_pyodbc', 
     'NAME': 'db_name', 
     'USER': 'db_user', 
     'PASSWORD': 'your_password',    
     'HOST': 'database.domain.com,1433', 
     'PORT': '1433', 
     'OPTIONS': { 
      'host_is_server': True, 
      'autocommit': True, 
      'unicode_results': True, 
      'extra_params': 'tds_version=8.0' 
     }, 
    } 
} 

如果你在Windows上,「extra_params」被忽略,但它使移植到Linux上。

+1

它是unicode_results鍵解決它? – holaSenor

+0

關鍵部分是'autocommit':對於這個問題(從Django 1.6開始)是正確的,但是如果您使用的是Python 3.x,則unicode_results行也是必需的。此外,我從這個答案中學到了一大堆 - 雖然8.0在當時被廣泛報道爲正確(並且仍然有效),但在FreeTDS下tds_version實際上應該是7.2。 – FlipperPA

0

這個問題解決了我們通過增加'driver_supports_utf8': True,'

'characteristics': { 
    'ENGINE': "django_pyodbc", 
    'HOST': "ourdbhost.com", 
    'PORT': 5555, 
    'NAME': "OurDB", 
    'USER': "ouruser", 
    'PASSWORD': "acoolpw", 
    'OPTIONS': { 
     'driver_supports_utf8': True, 
     'host_is_server': True, 
     'extra_params': 'TDS_Version=7.1', 
    }, 
}, 

擔任上https://github.com/lionheart/django-pyodbc/issues/47

加入

 'autocommit': True, 
     'unicode_results': True, 

OPTIONS沒有解決它建議通過GRI,但並沒有破壞任何東西要麼是