Форум сайта python.su
0
Суть такова: питоновский скрипт парсит текстовый файл в 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)
Офлайн
33
Питон 3 или 2?
Возможно, не хватает явного указания, что query содержит уникод.
Офлайн
33
Ну и cur.execute('SET NAMES utf8;') не помешает.
Офлайн
1
У меня вот так оно работает. Возвращается все корректно и работает без единой проблемы.
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)
Офлайн
0
Lexander
Питон 3 или 2?
Возможно, не хватает явного указания, что query содержит уникод.
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.
Офлайн
33
vaultЯ обратил внимание на отсутствие u перед строкой “INSERT IGNORE INTO ”.
Двойка. Оно и не содержит классический юникод - utf-8.
Офлайн
0
LexandervaultЯ обратил внимание на отсутствие u перед строкой “INSERT IGNORE INTO ”.
Двойка. Оно и не содержит классический юникод - utf-8.
Что выдает type(query)?
Офлайн
0
Дописал в создании таблицы к 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);
Офлайн
0
Спасибо, проблема решена. Тип поля в таблице был другой - не подходил значению. Понимаю, что дурак, но, честно говоря, не ожидал, что эта ошибка может выскакивать на такие события. Еще раз извините.
Офлайн
33
Эта ошибка всегда возникает, когда MySQL не может произвести автоматическую конвертацию строки, которую посылает приложение, в строку для сохранения в базе. Т.е. тип поля и передаваемая строка имеют разную кодировку (или тип).
Решение всегда одно и то же: привести строки к одному типу и кодировке.
Офлайн