无法将character_set_results设置为latin1

时间:2014-09-05 10:14:58

标签: python mysql django python-3.x django-orm

我决定第一次使用Python 3来使用Django 1.7。 我需要能够使用包含latin1数据的旧utf8数据库。我知道这很糟糕,但是数据库太庞大了,以至于无法改变它。所以我试着跟随:

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
    }
}

我还尝试过来自Oracle的python-mysql-connector以及以下设置

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],因为它包含用户名/密码并且成功连接到数据库
  • 当我在使用相同配置文件的linux终端中使用mysql命令时,一切都按预期工作

所以我猜Django以某种方式强制character_set_results变量为utf8。可能吗?有什么方法可以解决这个问题吗?

非常感谢

3 个答案:

答案 0 :(得分:2)

我终于明白了(我不知道为什么我总是在将它发布到SO之后找到解决方案)

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报告的错误。也许这会对某人有所帮助。

答案 1 :(得分:1)

这不是一个全面的答案,但对评论来说有点太长了......

Django的MySQL包装器将kwargs['charset']='utf8'设置为DatabaseWrapper.get_connection_params()中的默认值。然后将此dict传递给MySQLdb的Connection.__init__,该文档记录了:

  

字符集
      如果提供,连接字符集将被更改
      到这个字符集(MySQL-4.1和更新)。这意味着       use_unicode =真。

首先,您可以在"charset":"latin1"词典中添加OPTIONS吗?

警告:我不确定它是否能解决您的问题,甚至可能会产生其他问题但是,在latin1数据库中使用utf8编码数据肯定不是最好的起点: - /(在这里,做到了,我能感受到你的痛苦。)

答案 2 :(得分:0)

在client.cfg中使用mysql连接器python作为选项文件,代替init-command选项(连接器忽略)使用write,charset = latin1, 这将有效。

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