如何在SQLAlchemy的`create_engine`中使用`charset`和`encoding`(创建pandas数据帧)?

时间:2017-07-24 11:48:05

标签: mysql pandas sqlalchemy connection-string

我对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>

4 个答案:

答案 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")