Я пытаюсь сделать CSV некоторых данных из базы данных, чтобы переместить его в облако в хранилище данных. Однако, когда я запускаю его, он всегда заканчивается после 36599 строк и дает мне
UnicodeEncodeError: 'charmap' codec can't encode character '\x92' in position 62: character maps to <undefined>
Я обнаружил, что строка, вызывающая проблему, - "Номер отклоненного номера не соответствует", и я предполагаю, что это проблема с апострофом. Я не знаю, почему это вызывает эту проблему и не удалось найти способ ее решения. Кто-нибудь знает, как это решить? Код, который я использую:
db = pymysql.connect(host='host', port=3306, user="user", passwd="secret",
db="db", autocommit=True)
cur = db.cursor()
#cur.execute("call inv1_view_prod.'Email_agg'")
cur.execute("""select fields from table""")
emails = cur.fetchall()
with open('O:\file\path\to\File_name.csv','w') as fileout:
writer = csv.writer(fileout)
writer.writerows(emails)
time.sleep(1)
Поскольку вы не указали код, вызывающий ошибку, я просто догадываюсь.
Единственный факт состоит в том, что эта строка 'Rejected-Case No. doesnt match'
содержит символ ""
который является символом юникода U + 2019, ПРАВИЛЬНЫЙ ОДИН ЦИТАТ. На кодовой странице windows cp1252 этот символ действительно имеет код 0x92
.
Похоже, что у вас есть строка байтов, закодированная в charset cp1252, которая не была правильно декодирована в строку юникода.
Что нужно сделать:
Есть решения. К сожалению, они будут зависеть от версии Python, которую вы используете (2 или 3), и, не зная ничего из кода, я могу дать только общие советы:
error=replace
в вызовах кодирования/декодирования, чтобы избежать исключений UnicodeError. Если вы используете Python3, я предполагаю, что у вас есть проблема при декодировании unicode из базы данных. МАРКА ПРАВИЛЬНОЙ ОДИНОЧНОЙ ЦИТАТЫ имеет код Юникода U + 2019, но в строке, заданной для Python, кодируется '\x92'
которая является cp1252
байта cp1252
. Быстрое и грязное исправление - заставить проход кодирования/декодирования получить правильную строку юникода. Ваш код может стать:
db = pymysql.connect(host='host', port=3306, user="user", passwd="secret",
db="db", autocommit=True)
cur = db.cursor()
#cur.execute("call inv1_view_prod.'Email_agg'")
cur.execute("""select fields from table""")
charset = 'cp1252' # or 'utf8' depending on what you want in the csv file
with open('O:\file\path\to\File_name.csv','w', encoding=charset,
errors='replace', newline='') as fileout:
writer = csv.writer(fileout)
for row in cur.fetchall():
writer.writerow([field.encode('latin1').decode('cp1252', errors='replace')
for field in row])
encode('latin1').decode('cp1252')
- всего лишь трюк для исправления строки Python3, где символы имеют код байтовой кодировки. Он работает, потому что кодировка latin1
является не-операцией для всех кодов под 256.
Опция errors=replace
, попросите Python никогда не поднимать исключение UnicodeError, а вместо этого заменить оскорбительного символа символом '?'
для байтовой строки или с официальным Unicode ЗАМЕНЫ ХАРАКТЕР U + FFFD ' '
' '
для строки юникода.
Вероятно, было бы pymysql.connect
использовать опцию charset
для pymysql.connect
. К сожалению, я никогда не использовал базы данных MySQL из Python...
'\x92'
- ПРАВИЛЬНАЯ ОДНОКВАЖНАЯ МАРКА ЦИТАТЫ ('
) в кодировке cp1252