Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 8, 2012 16:16:14

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

Суть такова: питоновский скрипт парсит текстовый файл в utf-8 и обращается с insert-ами к mysql через MySQLdb. При этом творится что-то, чего я не понимаю.

Вот этот запрос проходит нормально:
INSERT IGNORE INTO PROFESSION (ID,NOMER,NAME,SUB_FAC_ID) VALUES (110,14300,'Физика Земли и планет',102);

Вот этот вызывает SQL-евский Warning: Incorrect string value, после которого выводится строка “медицинская физика” в utf-8:
INSERT IGNORE INTO PROFESSION (ID,NOMER,NAME,SUB_FAC_ID) VALUES (109,14000,'Медицинская физика',102);

А вот этот вызывает UnicodeEncodeError: ‘ascii can’t encode character u'\u0411': original not in range(128):
INSERT IGNORE INTO GROUP_ST (ID,NOMER,SUB_FAC_ID) VALUES (100,'Б8-01',100);

Объясните пожалуйста, почему так происходит?

Текст точно был конвертирован в utf-8.

Вот сам код:

#!/usr/bin/python
#-*- coding: utf-8  -*-
from MySQLdb import connections
FILE = open('data.txt')
HOST = 'localhost'
DBNAME = 'students'
USER = 'admin'
PASSWORD = 'pass'
def insert (title, header, vals):
	query="INSERT IGNORE INTO " + title + " (" + ','.join(header) \
		+ ") " + "VALUES (" + vals + ");"
    #Тут query точно в кодировке utf-8
	cur.execute(query)
	
con = connections.Connection(host=HOST, user=USER, passwd=PASSWORD, db=DBNAME, charset="utf8", use_unicode=True)
cur = con.cursor()
cond = "title"
for l in FILE.xreadlines():
	l = l.decode('utf-8').encode('utf-8')
	#Тут идет парсинг...
	insert(title, header, vals)
con.close()
FILE.close()

Отредактировано vault (Авг. 8, 2012 16:16:40)

Офлайн

#2 Авг. 8, 2012 17:15:35

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

Питон 3 или 2?
Возможно, не хватает явного указания, что query содержит уникод.



Офлайн

#3 Авг. 8, 2012 17:19:12

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

Ну и cur.execute('SET NAMES utf8;') не помешает.



Офлайн

#4 Авг. 8, 2012 17:35:44

Zerstoren
От:
Зарегистрирован: 2011-07-11
Сообщения: 17
Репутация: +  1  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

У меня вот так оно работает. Возвращается все корректно и работает без единой проблемы.

dbConnect = MySQLdb.connect(host=config.DB_HOST, user=config.DB_USER, passwd=config.DB_PASS, db=config.DB_BASE)
if dbConnect: 
    dbConnect.set_character_set('UTF8')



Отредактировано Zerstoren (Авг. 8, 2012 17:36:18)

Офлайн

#5 Авг. 8, 2012 20:58:33

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

Lexander
Питон 3 или 2?
Возможно, не хватает явного указания, что query содержит уникод.

Двойка. Оно и не содержит классический юникод - utf-8.

Lexander
Ну и cur.execute('SET NAMES utf8;') не помешает.
Это не пробовал - завтра потестю. Возникла идея, что может быть что-то с настройками мускля…

Zerstoren
dbConnect = MySQLdb.connect(host=config.DB_HOST, user=config.DB_USER, passwd=config.DB_PASS, db=config.DB_BASE)
if dbConnect:
dbConnect.set_character_set('UTF8')

Это делал - не помогает character_set там по умолчанию utf-8.

Офлайн

#6 Авг. 8, 2012 23:27:01

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

vault
Двойка. Оно и не содержит классический юникод - utf-8.
Я обратил внимание на отсутствие u перед строкой “INSERT IGNORE INTO ”.
Что выдает type(query)?



Офлайн

#7 Авг. 9, 2012 09:35:37

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

Lexander
vault
Двойка. Оно и не содержит классический юникод - utf-8.
Я обратил внимание на отсутствие u перед строкой “INSERT IGNORE INTO ”.
Что выдает type(query)?

str конечно. Я и не понимаю: если я пихаю код в utf-8, зачем его вообще питону в юникод перегонять и обратно?
Пихать юникод тоже пробовал - результат тот же.

Офлайн

#8 Авг. 9, 2012 09:47:23

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

Дописал в создании таблицы к default character set utf8 фразу collate utf8_general_ci, ворнинги исчезли, а ошибка нет:

А вот этот вызывает UnicodeEncodeError: ‘ascii can’t encode character u'\u0411': original not in range(128):
INSERT IGNORE INTO GROUP_ST (ID,NOMER,SUB_FAC_ID) VALUES (100,'Б8-01',100);

u0411 - юникодная “Б”. При этом выше буква “Б” встречалась, но ошибки не вызывала.

Офлайн

#9 Авг. 9, 2012 10:05:22

vault
Зарегистрирован: 2012-06-21
Сообщения: 52
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

Спасибо, проблема решена. Тип поля в таблице был другой - не подходил значению. Понимаю, что дурак, но, честно говоря, не ожидал, что эта ошибка может выскакивать на такие события. Еще раз извините.

Офлайн

#10 Авг. 9, 2012 14:47:27

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Проблемы с кодировкой при работе с MySQLdb

Эта ошибка всегда возникает, когда MySQL не может произвести автоматическую конвертацию строки, которую посылает приложение, в строку для сохранения в базе. Т.е. тип поля и передаваемая строка имеют разную кодировку (или тип).
Решение всегда одно и то же: привести строки к одному типу и кодировке.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version