我对charset和encoding在 SQLAlchemy 中的工作方式感到很困惑。我理解(并且已阅读)charsets and encodings之间的区别,我对the history of encodings有了很好的了解。
我在MySQL中有一个表latin1_swedish_ci (为什么?可能因为this)。我需要创建一个pandas数据帧,在其中我得到正确的字符(而不是奇怪的符号)。最初,这是在代码中:
connect_engine = create_engine('mysql://user:password@1.1.1.1/db')
sql_query = "select * from table1"
df = pandas.read_sql(sql_query, connect_engine)
我们开始遇到Š
字符(与u'\u0160'
unicode相对应的问题,但我们得到了' \ x8a')。我希望这可行:
connect_engine = create_engine('mysql://user:password@1.1.1.1/db', encoding='utf8')
但是,我继续得到'\x8a'
,我意识到,鉴于编码参数的默认值为utf8
,这是有意义的。那么,我尝试encoding='latin1'
来解决这个问题:
connect_engine = create_engine('mysql://user:password@1.1.1.1/db', encoding='latin1')
但是,我仍然得到相同的' \ x8a'。为了清楚起见,在这两种情况下(encoding='utf8'
和encoding='latin1'
),我可以mystring.decode('latin1')
而不是mystring.decode('utf8')
。
然后,我重新发现了连接字符串中的charset
参数,即'mysql://user:password@1.1.1.1/db?charset=latin1'
。在尝试了所有可能的字符集和编码组合后,我发现这个工作:
connect_engine = create_engine('mysql://user:password@1.1.1.1/db?charset=utf8')
如果有人能解释我如何正确使用连接字符串中的charset
以及encoding
中的create_engine
参数? <我将不胜感激/ p>
答案 0 :(得分:6)
encoding
参数无效。
因此,正如@doru在this link中所说,您应该在连接字符串的末尾添加?charset=utf8mb4
。像这样:
connect_string = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8mb4'.format(DB_USER, DB_PASS, DB_HOST, DB_PORT, DATABASE)
答案 1 :(得分:3)
encoding
是用于在SQLAlchemy 中编码/解码的编解码器。来自文档:
对于检测到DBAPI不支持a的情况 Python
unicode
对象,这个编码用于确定 源/目标编码。 未使用用于那些情况 DBAPI直接处理unicode。[...]
正确配置系统以容纳Python
unicode
个对象, 应该将DBAPI配置为最大程度地处理unicode 适当的程度[...]
mysql-python直接处理unicode,因此无需使用此设置。
charset
是特定于mysql-python驱动程序的设置。来自the documentation:
此charset是连接的客户端字符集。
此设置控制服务器上的three variables,特别是character_set_results
,这是您感兴趣的内容。设置后,字符串将作为unicode
个对象返回。
请注意,这仅适用于数据库中包含latin1编码数据的情况。如果你将utf-8字节存储为latin1,那么使用encoding
可能会更好运。
答案 2 :(得分:1)
这适合我。
from sqlalchemy import create_engine
from sqlalchemy.engine.url import URL
db_url = {
'database': "dbname",
'drivername': 'mysql',
'username': 'myname',
'password': 'mypassword',
'host': '127.0.0.1',
'query': {'charset': 'utf8'}, # the key-point setting
}
engine = create_engine(URL(**db_url), encoding="utf8")
答案 3 :(得分:1)
我遇到了同样的问题。我刚刚在网址末尾添加了?charset = utf8mb4 。
这是我的:
<强>之前强>
SQL_ENGINE = sqlalchemy.create_engine('mysql+pymysql://'+MySQL.USER+':'+MySQL.PASSWORD+'@'+MySQL.HOST+':'+str(MySQL.PORT)+'/'+MySQL.DB_NAME)
<强>后强>
SQL_ENGINE = sqlalchemy.create_engine('mysql+pymysql://'+MySQL.USER+':'+MySQL.PASSWORD+'@'+MySQL.HOST+':'+str(MySQL.PORT)+'/'+MySQL.DB_NAME + "?charset=utf8mb4")