Найти - Пользователи
Полная версия: Проблемы с кодировкой при работе с MySQLdb
Начало » Python для новичков » Проблемы с кодировкой при работе с MySQLdb
1
vault
Суть такова: питоновский скрипт парсит текстовый файл в 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()
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')
vault
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.
Lexander
vault
Двойка. Оно и не содержит классический юникод - utf-8.
Я обратил внимание на отсутствие u перед строкой “INSERT IGNORE INTO ”.
Что выдает type(query)?
vault
Lexander
vault
Двойка. Оно и не содержит классический юникод - utf-8.
Я обратил внимание на отсутствие u перед строкой “INSERT IGNORE INTO ”.
Что выдает type(query)?

str конечно. Я и не понимаю: если я пихаю код в utf-8, зачем его вообще питону в юникод перегонять и обратно?
Пихать юникод тоже пробовал - результат тот же.
vault
Дописал в создании таблицы к 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 - юникодная “Б”. При этом выше буква “Б” встречалась, но ошибки не вызывала.
vault
Спасибо, проблема решена. Тип поля в таблице был другой - не подходил значению. Понимаю, что дурак, но, честно говоря, не ожидал, что эта ошибка может выскакивать на такие события. Еще раз извините.
Lexander
Эта ошибка всегда возникает, когда MySQL не может произвести автоматическую конвертацию строки, которую посылает приложение, в строку для сохранения в базе. Т.е. тип поля и передаваемая строка имеют разную кодировку (или тип).
Решение всегда одно и то же: привести строки к одному типу и кодировке.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB