我正在使用sqlalchemy来创建我的数据库的架构。无论我怎么做,我都没有成功地使用utf-8。
这是一个重新创建我的问题的最小python脚本:
from sqlalchemy import create_engine, Column, Unicode
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('mysql+mysqldb://user:password@localhost/multidic?charset=utf8', echo=True)
Base = declarative_base()
class MyTableName(Base):
__tablename__ = "mytablename"
test_column = Column(Unicode(2),primary_key=True)
Base.metadata.create_all(engine)
运行此脚本后,当我查看数据库时,我发现编码是latin1而不是utf-8:
mysql> SHOW FULL COLUMNS FROM mytablename;
+-------------+------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+-------------+------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
| test_column | varchar(2) | latin1_swedish_ci | NO | PRI | NULL | | select,insert,update,references | |
+-------------+------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
1 row in set (0.00 sec)
我尝试更改创建的列的类型(字符串而不是 Unicode ),并尝试添加参数 encoding =“utf8”< / strong>在 create_engine 的调用中,但都没有效果。
所以,我的问题是:
如何使用sqlalchemy强制在MySQL中强制使用给定的字符编码(在我的情况下是utf-8)?
谢谢:)
我正在使用sqlalchemy 0.7和python 2.7;我可以升级其中一个或两个,但前提是它是唯一的解决方案!
我有mysql 5,它支持utf-8:
mysql> show character set where charset="utf8";
+---------+---------------+-------------------+--------+
| Charset | Description | Default collation | Maxlen |
+---------+---------------+-------------------+--------+
| utf8 | UTF-8 Unicode | utf8_general_ci | 3 |
+---------+---------------+-------------------+--------+
1 row in set (0.00 sec)
答案 0 :(得分:16)
要为每列指定特定的排序规则,请在数据类型上使用collation
参数:
class MyTableName(Base):
__tablename__ = "mytablename2"
test_column = Column(Unicode(2),
primary_key=True)
test_column2 = Column(Unicode(2, collation='utf8_bin'))
# ^^^^^^^^^^^^^^^^^^^^
请注意,MySQL将此理解为描述文本的代码点集以及文本将被编入索引的排序顺序;像'utf8'或'utf-8'这样的常见嫌疑人对MySQL不熟悉(使用SHOW COLLATION
查看完整列表)
mysql> show full columns from mytablename2;
+--------------+------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+--------------+------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
| test_column | varchar(2) | latin1_swedish_ci | NO | PRI | NULL | | select,insert,update,references | |
| test_column2 | varchar(2) | utf8_bin | YES | | NULL | | select,insert,update,references | |
+--------------+------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
2 rows in set (0.00 sec)
mysql>
答案 1 :(得分:2)
对我来说,校对参数不起作用。
我的连接字符串是:
db = create_engine('mysql+pymysql://user:pass@dbhost/schema?charset=utf8')
由于charset,Pymysql正在执行set name utf8,数据库正在将utf8转换为表的编码,导致数据丢失。
如果我离开charset,charset默认为latin1,pymysql尝试将我的utf8字符串编码为latin1,然后再将它们发送到数据库,从而导致UnicodeEncode错误。
这对我有用:session.execute(text("SET NAMES latin1"))
使数据库假定我发送的utf8字符串不需要转换。