【发布时间】: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';说什么? -
嗯,看来你有什么了不起的。它给出了两个结果:
NULL和latin1。不确定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