pysqlite2: ProgrammingError — вы не должны использовать 8-битные строки байтов

В настоящее время я сохраняю имена файлов в базе данных sqlite для своих целей. Всякий раз, когда я пытаюсь вставить файл со специальным символом (например, é и т. д.), он выдает следующую ошибку:

pysqlite2.dbapi2.ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.

Когда я «переключаю свое приложение на строки Unicode», упаковывая значение, отправленное в pysqlite, с помощью метода unicode, например: unicode(filename), он выдает эту ошибку:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 66: ordinal not in range(128)

Есть ли что-то, что я могу сделать, чтобы избавиться от этого? Изменение всех моих файлов для соответствия не вариант.

ОБНОВЛЕНИЕ Если я декодирую текст с помощью filename.decode("utf-8"), я все еще получаю указанную выше ошибку ProgrammingError.

Мой фактический код выглядит так:

cursor.execute("select * from musiclibrary where absolutepath = ?;",
    [filename.decode("utf-8")])

Как должен выглядеть мой код здесь?


person Naftuli Kay    schedule 14.05.2010    source источник
comment
Похоже, что этот код после того, как вы обновили вопрос, на самом деле не был кодом, вызвавшим ошибку, верно?   -  person metamatt    schedule 11.01.2011
comment
Да, это был аналогичный код позже в приложении.   -  person Naftuli Kay    schedule 12.01.2011


Ответы (5)


Вам нужно указать кодировку filename для преобразования в Unicode, например: filename.decode('utf-8'). Простое использование unicode(...) выбирает кодировку консоли, которая часто ненадежна (и часто ascii).

person Nicholas Riley    schedule 14.05.2010
comment
Я пытался это сделать, но кажется, что я все еще получаю ошибки, упомянутые выше. Я обновил сообщение тем, что я делаю сейчас, чтобы вы могли видеть, что я делаю. Спасибо! - person Naftuli Kay; 15.05.2010
comment
Плохо, позже в моем скрипте произошло еще одно плохое преобразование, которое выдавало ту же ошибку :) - person Naftuli Kay; 15.05.2010

Вы должны передать как Unicode аргументы вашего оператора SQL.

Теперь все зависит от того, как вы получите список имен файлов. Возможно, вы читаете файловую систему, используя os.listdir или os.walk? Если это так, есть способ получить имена файлов непосредственно в формате Unicode, просто передав аргумент Unicode любой из этих функций:
Примеры:

  • os.listdir(u'.')
  • os.walk(u'.')

Конечно, вы можете заменить каталог u'.' фактическим каталогом, содержимое которого вы читаете. Просто убедитесь, что это строка Unicode.

person tzot    schedule 10.06.2010

Вы пытались передать строку юникода напрямую:

cursor.execute("select * from musiclibrary where absolutepath = ?;",(u'namé',))

Вам нужно будет добавить кодировку файла в начало скрипта:

# coding: utf-8
person newtover    schedule 15.05.2010
comment
Если я попробую это, это, кажется, работает. Я перебираю около 3000 файлов, и это не удается с именем файла, например: 02 - Neighborhood # 2 (Laïka).mp3 . Есть ли техника преобразования, которую я где-то упустил? - person Naftuli Kay; 15.05.2010

Вы уже поняли это, но:

Я не думаю, что вы действительно могли бы получить это исключение ProgrammingError из cursor.execute("select * from musiclibrary where absolutepath = ?;", [filename.decode("utf-8")]), как в настоящее время говорится в вопросе.

Либо декодирование utf-8 взорвется, либо вызов cursor.execute будет доволен результатом.

person metamatt    schedule 11.01.2011

Попробуйте изменить на это:

cursor.execute("select * from musiclibrary where absolutepath = ?;",
    [unicode(filename,'utf8')])

В вашем имени файла не кодируется utf8, измените utf8 на вашу кодировку.

person shxzhaosr    schedule 19.08.2017