【问题标题】:UTF-8 not working when connecting to MySQL database in Python在 Python 中连接到 MySQL 数据库时,UTF-8 不起作用
【发布时间】:2015-11-24 20:35:39
【问题描述】:

我正在努力使 Python 与我的 UTF-8 编码的 MySQL 数据库配合使用,例如挪威字符 æøå。我已经搜索了几个小时,但找不到任何可以按预期工作的东西。这是从数据库中提取的示例表:

mysql> select * from my_table;
+----+-----------------+
| id | shop_group_name |
+----+-----------------+
|  1 | Frukt og grønt  |
|  2 | Kjøtt og fisk   |
|  3 | Meieriprodukter |
|  4 | Frysevarer      |
|  5 | Bakevarer       |
|  6 | Tørrvarer       |
|  7 | Krydder         |
|  8 | Hermetikk       |
|  9 | Basisvarer      |
| 10 | Diverse         |
+----+-----------------+
10 rows in set (0.00 sec)

所以数据肯定是 UTF-8 编码的。但是,在运行以下 Python 代码时,它不会给出输出 int UTF-8。它有什么问题?它与拉链无关; cursor.execute(query) 返回的元组已经搞乱了编码。

#!/usr/bin/env python
import MySQLdb

db = MySQLdb.connect(host="localhost",
                     user="test",
                     passwd="passwd",
                     db="mydb",
                     charset='utf8',
                     use_unicode=True)

# Set desired conversion of data.
db.converter[MySQLdb.FIELD_TYPE.NEWDECIMAL] = float
db.converter[MySQLdb.FIELD_TYPE.DATETIME] = str
db.converter[MySQLdb.FIELD_TYPE.LONGLONG] = int
db.converter[MySQLdb.FIELD_TYPE.LONG] = int
db.converter[MySQLdb.FIELD_TYPE.DATETIME] = str
db.converter[MySQLdb.FIELD_TYPE.DATETIME] = str
db.converter[MySQLdb.FIELD_TYPE.DATETIME] = str

cursor = db.cursor()
query = 'SELECT * FROM my_table'

allResults = {}
cursor.execute(query)
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
results = []
for row in rows:
    row = dict(zip(columns, row))
    results.append(row)
allResults['my_table'] = results

cursor.close()
db.close()

allResults 字典现在包含:

{
    'my_table': [
        {
            'id': 1,
            'shop_group_name': 'Fruktoggr\xf8nt'
        },
        {
            'id': 2,
            'shop_group_name': 'Kj\xf8ttogfisk'
        },
        {
            'id': 3,
            'shop_group_name': 'Meieriprodukter'
        },
        {
            'id': 4,
            'shop_group_name': 'Frysevarer'
        },
        {
            'id': 5,
            'shop_group_name': 'Bakevarer'
        },
        {
            'id': 6,
            'shop_group_name': 'T\xf8rrvarer'
        },
        {
            'id': 7,
            'shop_group_name': 'Krydder'
        },
        {
            'id': 8,
            'shop_group_name': 'Hermetikk'
        },
        {
            'id': 9,
            'shop_group_name': 'Basisvarer'
        },
        {
            'id': 10,
            'shop_group_name': 'Diverse'
        }
    ]
}

我真的看不出我做错了什么。我正在 Ubuntu 的 Python 2.7.6 中运行测试。

更新(将表更改为 UTF-8)

我尝试通过转储数据库并更改转储文件中的字符集和排序规则将表更改为 UTF-8,然后将其插入新数据库。例如,转储文件的这部分对应于上面的示例。原来是这样的:

DROP TABLE IF EXISTS `my_table`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `my_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `shop_group_name` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

这就是我将这部分更改为:

DROP TABLE IF EXISTS `my_table`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `my_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `shop_group_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

但是,这仍然不起作用。输出仍然与上面相同。运行 SELECT CHARACTER_SET_NAME FROM information_schema.columns WHERE TABLE_NAME = 'my_table'; 现在会生成 utf8

【问题讨论】:

  • 您的列是 UTF-8 吗?您的输出数据看起来像 latin-1(在 UTF-8 中,ø 是 0xC3B8,在 latin-1 中是 0xF8)。 select character_set_name from information_schema.columns where table = 'my_table'; 说什么?
  • 嗯,看来你有什么了不起的。它给出了两个结果:NULLlatin1。不确定NULL 是什么,但latin1 不是我所期望/想到的。出于某种原因,latin1 也给出了COLLATION_NAME = latin1_swedish_ci。我如何在MySQLdb 中使用它?哦,为了完整起见,查询是SELECT CHARACTER_SET_NAME FROM information_schema.columns WHERE TABLE_NAME = 'my_table';。 (即TABLE_NAME,而不是TABLE)。
  • SELECT col, hex(col) FROM tbl WHERE ... -- 让我们看看它是 F8 还是 C3B8

标签: python mysql encoding utf-8 mysql-python


【解决方案1】:

当您创建表时,以 UTF-8 创建列:

CREATE TABLE my_table (
    ...
    shop_group_name VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci
);

如果您不指定字符集和排序规则,那么 MySQL 使用默认的字符集和排序规则。或者,您可以在mysql.cnf 中设置默认值。

【讨论】:

  • 我尝试按照帖子更新中的说明将表更改为 UTF-8,但它仍然没有提供正确的输出。您还有什么建议吗?
  • 我也尝试使用CREATE DATABASE mydb DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci; 创建一个新数据库,然后使用CHARACTER SET utf8 COLLATE utf8_general_ci 创建适当的表,但它没有改变任何东西。
猜你喜欢
  • 2012-03-05
  • 2022-12-14
  • 2016-01-31
  • 1970-01-01
  • 1970-01-01
  • 2018-11-09
  • 2014-05-20
  • 1970-01-01
  • 2013-01-29
相关资源
最近更新 更多