我决定第一次使用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
client.cfg
文件并更正[section]
,因为它包含用户名/密码并且成功连接到数据库mysql
命令时,一切都按预期工作所以我猜Django以某种方式强制character_set_results
变量为utf8
。可能吗?有什么方法可以解决这个问题吗?
非常感谢
答案 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-connector
或Django
报告的错误。也许这会对某人有所帮助。
答案 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