2014-09-05 81 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