【问题标题】:Django Encoding Issues with MySQLMySQL 的 Django 编码问题
【发布时间】:2010-05-14 02:19:12
【问题描述】:

好的,我已经建立了一个 MySQL 数据库。大多数表都是 latin1 并且 Django 可以很好地处理它们。但是,其中一些是 UTF-8,Django 不处理它们。

这是一个示例表(这些表都来自 django-geonames):

DROP TABLE IF EXISTS `geoname`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `geoname` (
  `id` int(11) NOT NULL,
  `name` varchar(200) NOT NULL,
  `ascii_name` varchar(200) NOT NULL,
  `latitude` decimal(20,17) NOT NULL,
  `longitude` decimal(20,17) NOT NULL,
  `point` point default NULL,
  `fclass` varchar(1) NOT NULL,
  `fcode` varchar(7) NOT NULL,
  `country_id` varchar(2) NOT NULL,
  `cc2` varchar(60) NOT NULL,
  `admin1_id` int(11) default NULL,
  `admin2_id` int(11) default NULL,
  `admin3_id` int(11) default NULL,
  `admin4_id` int(11) default NULL,
  `population` int(11) NOT NULL,
  `elevation` int(11) NOT NULL,
  `gtopo30` int(11) NOT NULL,
  `timezone_id` int(11) default NULL,
  `moddate` date NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `country_id_refs_iso_alpha2_e2614807` (`country_id`),
  KEY `admin1_id_refs_id_a28cd057` (`admin1_id`),
  KEY `admin2_id_refs_id_4f9a0f7e` (`admin2_id`),
  KEY `admin3_id_refs_id_f8a5e181` (`admin3_id`),
  KEY `admin4_id_refs_id_9cc00ec8` (`admin4_id`),
  KEY `fcode_refs_code_977fe2ec` (`fcode`),
  KEY `timezone_id_refs_id_5b46c585` (`timezone_id`),
  KEY `geoname_52094d6e` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;

现在,如果我尝试使用 MySQLdb 和游标直接从表中获取数据,我会得到正确编码的文本:

>>> import MySQLdb
>>> from django.conf import settings
>>> 
>>> conn = MySQLdb.connect (host = "localhost",
... user = settings.DATABASES['default']['USER'],
... passwd = settings.DATABASES['default']['PASSWORD'],
... db = settings.DATABASES['default']['NAME'])
>>> cursor = conn.cursor ()
>>> cursor.execute("select name from geoname where name like 'Uni%Hidalgo'");
1L
>>> g = cursor.fetchone()
>>> g[0]
'Uni\xc3\xb3n Hidalgo'
>>> print g[0]
Unión Hidalgo

但是,如果我尝试使用 Geoname 模型(实际上是 django.contrib.gis.db.models.Model),它会失败:

>>> from geonames.models import Geoname
>>> g = Geoname.objects.get(name__istartswith='Uni',name__icontains='Hidalgo')
>>> g.name
u'Uni\xc3\xb3n Hidalgo'
>>> print g.name
Unión Hidalgo

这里很明显存在编码错误。在这两种情况下,数据库都返回“Uni\xc3\xb3n Hidalgo”,但 Django 正在(错误地?)将“\xc3\xb3n”翻译为 ó。

我能做些什么来解决这个问题?

更新

好的,这很奇怪:

>>> c = unicode('Uni\xc3\xb3n Hidalgo','utf-8')
>>> c
u'Uni\xf3n Hidalgo'
>>> print c
Unión Hidalgo

如果我 强制 python 将字符串从 utf-8 编码为 Unicode,它可以工作。但是,这会重现错误:

>>> c = unicode('Unión Hidalgo','latin1')
>>> c
u'Uni\xc3\xb3n Hidalgo'
>>> print c
Unión Hidalgo

所以,我猜 MySQL 发送的是 utf-8 但告诉 Python 它是 latin1?

【问题讨论】:

    标签: mysql django encoding


    【解决方案1】:

    你可以这样使用

    >>> print g.name.encode('latin1')
    Unión Hidalgo
    

    【讨论】:

    • 我真的不能在需要这个值的任何地方都这样做。我可以对 MySQL 或 Django 做些什么来让它们正常工作吗?
    【解决方案2】:

    看来问题出在 MySQL 上。我删除了表格,使用设置为 UTF 的 charset 和 collat​​e 重新创建它们,然后重新导入了所有数据。

    现在可以了。

    【讨论】:

      【解决方案3】:

      Django 1.10、MariaDB 5.5.47


      一个很重要的事情是在创建数据库的时候设置数据库的字符集:

      CREATE DATABASE `my_database` CHARACTER SET utf8;
      

      然后你可以查看你的mysql的配置文件/etc/my.cnf(我用的是MariaDB):

      [client]
      default-character-set=utf8
      
      [mysql]
      default-character-set=utf8
      
      [mysqld]
      datadir=/var/lib/mysql
      socket=/var/lib/mysql/mysql.sock
      # Disabling symbolic-links is recommended to prevent assorted security risks
      symbolic-links=0
      # Settings user and group are ignored when systemd is used.
      # If you need to run mysqld under a different user or group,
      # customize your systemd unit file for mariadb according to the
      # instructions in http://fedoraproject.org/wiki/Systemd
      collation-server=utf8_unicode_ci
      init-connect='SET NAMES utf8'
      character-set-server=utf8
      

      还要记得重启你的sqlservice:

      sudo systemctl restart mariadb.service
      

      参考:

      https://docs.djangoproject.com/en/1.10/ref/databases/#creating-your-database https://mariadb.com/kb/en/the-mariadb-library/setting-character-sets-and-collations/

      【讨论】:

        猜你喜欢
        • 2012-02-21
        • 1970-01-01
        • 2010-12-15
        • 1970-01-01
        • 1970-01-01
        • 2015-01-24
        • 2014-01-22
        • 2021-10-29
        相关资源
        最近更新 更多