Otro UnicodeEncodeError cuando se usa el método de pandas to_sql con MySQL

Hace unos días publiqué en el desbordamiento de stack con un problema similar (que se resolvió), y no estoy seguro de cuál es la etiqueta adecuada aquí, pero estoy haciendo una nueva publicación.

Básicamente, obtengo un UnicodeEncodeError cuando bash escribir un DataFrame de pandas en una base de datos MySQL. Puedo reproducir el error con el siguiente código:

import pandas as pd from sqlalchemy import create_engine engine = create_engine('mysql://root:@localhost/testdb') df = pd.DataFrame([[u'\u2013',2],['e',4]], index = ['a','b'], columns = ['c','d']) df.to_sql('data', engine, if_exists = 'replace', index = False) 

Aquí está el error:

 UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2013' in position 0: ordinal not in range(256) 

Y esta es la última línea relevante del rastreo:

 C:\Anaconda\lib\site-packages\sqlalchemy\dialects\mysql\mysqldb.pyc in do_executemany(self, cursor, statement, parameters, context) 93 94 def do_executemany(self, cursor, statement, parameters, context=None): ---> 95 rowcount = cursor.executemany(statement, parameters) 96 if context is not None: 97 context._rowcount = rowcount 

Cuando tuve este problema antes, se debió a un error en pandas.io.sql, y la solución fue cambiar algunas líneas de código . Esto funcionó bien hasta que encontré caracteres fuera del rango del códec de latin-1.

¿Tienen alguna sugerencia?

Bueno, una hora después de publicar mi pregunta, ya lo descubrí. Tal vez debería haber hecho un poco más de investigación antes de publicar.

El problema es que sqlalchemy necesita configurarse para usar la encoding utf-8. La solución en el código anterior sería cambiar la línea 3 a:

 engine = create_engine('mysql://root:@localhost/testdb?charset=utf8', encoding = 'utf-8') 

\u2013 es un “en dash”. Tal vez algún procesador de textos está creando eso? Tal vez sería lo suficientemente feliz con un simple - ?

Ver https://docs.sqlalchemy.org/en/latest/dialects/mysql.html#mysql-unicode