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)

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

UPDATE Если я декодирую текст через filename.decode("utf-8"), я все равно получаю Программирование выше.

Мой фактический код выглядит следующим образом:

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

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

Ответы

Ответ 1

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

# coding: utf-8

Ответ 4

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

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

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

Ответ 5

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

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

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