2014-09-05 58 views
2

我已決定首次使用Django 1.7與Python 3. 我需要能夠使用包含utf8數據的舊版latin1數據庫。我知道這很糟糕,但是數據庫非常龐大,所以改變這一點是不可能的。所以我嘗試以下操作:無法將character_set_results設置爲latin1

DATABASES = { 
    'ENGINE' : 'django.db.backends.mysql', // using MySQL-python fork with support for py3 
    ... 
    'OPTIONS' : { 
     'init_command': "SET character_set_results = 'latin1'", 
     #'read_default_file': '/etc/my.cnf.d/client.cnf', // I've also tried this one 
    } 
} 

我也試着從甲骨文中的python-mysql的連接器具有以下設置

DATABASES = { 
    'ENGINE' : 'mysql.connector.django', // using MySQL-python fork with support for py3 
    'OPTIONS' : { 
     'option_files': ['/etc/my.cnf.d/client.cnf'], 
    } 
} 

/etc/my.cnf.d/client.cnf

[client] 
init-command='SET character_set_results = "latin1"' 
# password, host, username 

在這兩種情況下,我都可以連接到數據庫,但好像Django會將character_set_results設置回utf8。

我已經試過以下

from django.db import connection 

with connection.cursor() as c: 
    // I expect variable to be 'latin1' 
    c.execute("show variables like 'character_set_results%'") 
    c.fetchone() // returns ('character_set_results', 'utf8') 

    // here I try to set it manually 
    c.execute("SET character_set_results = 'latin1'") 
    c.execute("show variables like 'character_set_results%'") 
    c.fetchone() // returns ('character_set_results', 'latin1') // now it's OK 
  • 我敢肯定,Django使用client.cfg文件和正確[section],因爲它包含的用戶名/密碼,併成功連接到數據庫
  • 當我使用mysql命令在使用相同配置文件的linux終端中,一切按預期工作

所以我想Django強制執行character_set_results變量是utf8。可能嗎?有什麼辦法可以解決這個問題嗎?

非常感謝您

回答

2

我終於想通了(我不知道爲什麼,我總是張貼到打完了,而找到一個解決方案)

from django.db.backends.signals import connection_created 

def connection_setup(**kwargs): 
    conn = kwargs['connection'] 
    with conn.cursor() as cursor: 
     cursor.execute("SET character_set_results = 'latin1'") 
     cursor.close() 

我以前與Oracle的python-mysql-connector嘗試過了,它扔

RuntimeError: maximum recursion depth exceeded in comparison

但它適用於MySQL-driver py3分支。我想這可能是我會報告的python-mysql-connectorDjango中的一個錯誤。也許這會幫助某人。

+0

如果mysql連接器python拋出運行時錯誤,請報告bugs.mysql.com上的錯誤。 – Peeyush 2014-09-05 18:06:48

+0

我還需要調用'conn.connection.set_character_set(「latin1」)'以確保mysql連接中的string_decoder使用正確的字符集進行字符串到Unicode的轉換......(mysql-python = 1.2.3, django = 1.4,mysql = 5.6) – 2015-02-11 14:04:04

+0

如何設置全局所有遊標默認情況下都必須是latin-1?因爲我的數據庫所有字符字段是latin1?謝謝 – giaosudau 2015-04-15 14:46:20

1

不是一個真正的全面的回答,但有點太長評論所以...

Django的MySQL的包裝套kwargs['charset']='utf8'作爲默認DatabaseWrapper.get_connection_params()。然後,這個字典傳遞給MySQLdb的的Connection.__init__,其中記錄了:

字符集
如果提供,連接字符集將改爲
這個字符集(在MySQL-4.1和更高版本)。這意味着
use_unicode = True。

所以一個出發點可能是在您的OPTIONS字典中只加"charset":"latin1"字典?

警告:我不確定它會解決你的問題,它甚至可能會產生其他問題,但是,在一個latin1數據庫中使用utf8編碼的數據肯定不是最好的出發點: - /(在這裏完成那個,我能感覺到你的痛苦)。

+0

感謝您的評論,我也試着設置'「字符集」:在「latin1」''中OPTIONS',可惜的是,沒有運氣 – 2014-09-05 11:17:00

+0

+1對我保證這是Django的內部系統,該系統設置參數,幫我找到答案,謝謝 – 2014-09-05 11:45:48

0

使用mysql連接器python在client.cfg中用作選項文件,而不是使用init-command選項(連接器將忽略此選項)使用write,charset = latin1, 這將起作用。

[client] 
charset=latin1 
# password, host, username 
+0

這不會起作用,它與'init-command'具有相同的效果,問題在於Django總是覆蓋這個變量,我在我的答案中解釋了它 – 2014-09-06 14:46:22