ошибка 8-разрядной байтовой строки в pysqlite при вставке данных unicode

#python #sqlite #unicode

#python #sqlite #unicode

Вопрос:

Я знаю, что подобные перестановки этого вопроса задавались ранее, но ответы, похоже, не проливают свет на то, что я здесь делаю неправильно.

Я пытаюсь вставить эту строку: (Pdb) строка печати [‘886′, ’39’, ‘83474’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘1.00’, ‘ D’, ‘20070813’, ‘R’, ‘C’, ‘B’, «НОСОК 4PK», ‘xe9 x9ex8b xe5xadx90xe5xb0xbaxe5xafxb86-9.5/24-27.5 СМ’, ‘PR’]

в эту таблицу: СОЗДАЙТЕ элемент ТАБЛИЦЫ («whs» int, «dept» int, «item» int, «dsun» int, «oh» int, «ohrtv» int, «adjp» int, «adjn» int, «sell» text, «stat» text, «lsldt» int, «cat1» text, «cat2» text, «cat3» text, «des1» text, «sgn3″ text, » единица измерения» текст);

Похоже, что проблемы вызывает столбец sgn3. Она определена как ТЕКСТ, и данные, которые должны быть вставлены, имеют формат utf-8. Почему я получаю ошибку sqlite3?

Ошибка программирования: ‘Вы не должны использовать 8-разрядные байтовые строки, если вы не используете text_factory, который может интерпретировать 8-разрядный байтовый код (…= str). Настоятельно рекомендуется вместо этого просто переключить ваше приложение на строки Unicode.’

Вот код, выполняющий вставку:

 query = 'insert into %s values(%s)' % (
    self.tablename,
    ','.join(['?' for field in row])
)
self.con.execute(query, row)
  

И вот процедура, которая создает генератор записей для вставки:

 def encode_utf_8(self, csv_data, csv_encoding):
    """Decodes from 'csv_encoding' and encodes to utf-8.  

    Accepts any open csv file encoding using any scheme recognized by 
    python. Returns a generator.  

    """
    for line in csv_data:
        try:
            yield line.decode(csv_encoding).encode('utf-8')
        except UnicodeDecodeError:
            next
  

Ответ №1:

Это одно из самых полезных сообщений об ошибках, которые я когда-либо видел. Просто делайте то, что он говорит. Передайте им unicode объекты, а не объекты в кодировке UTF-8 str . Другими словами, потеряйте .encode('utf-8') или, возможно, выполните это позже путем декодирования (‘utf-8’) …что именно это csvdata ?

Если вы когда-либо получите ошибку UnicodeDecodeError в вашем существующем коде:

(1) Вы должны сделать что-то гораздо более полезное, чем то, что вы намеревались с этим сделать (убрать это под ковер)

(2) Возможно, вы захотите изменить next на pass

Ответ на комментарий

ха-ха, это очень полезное сообщение об ошибке

хаха??? Я не шутил; это точно говорит вам, что делать.

csvdata — это csv-файл, в данном случае в кодировке big5 в python 2.x

Что вы называете «файлом csv»:

 (1) csvdata = open('my_big5_file', 'rb')
(2) csvdata = csv.reader(open('my_big5_file', 'rb'))
(3) other; please specify 
  

если бы я решил не кодировать в utf-8, мой
строки в формате ascii правильные?

Совершенно неверно. bytes_read_from_file.decode('big5') создает unicode объект. Возможно, вам захочется прочитать руководство по Python Unicode.

итак, мне нужно явно изменить их на unicode перед сохранением в базе данных?

Нет, они unicode уже есть. Однако, в зависимости от того, что csvdata есть, вы можете захотеть закодировать в utf8 , чтобы получить их через механизм csv, а затем декодировать их позже.

Комментарии:

1. ха-ха, это очень полезное сообщение об ошибке csvdata — это csv-файл, в данном случае в кодировке big5 в python 2.x если я решил не кодировать в utf-8, мои строки будут в формате ascii, верно? итак, мне нужно явно изменить их на unicode перед сохранением в базе данных?