Ошибка кодирования/декодирования Python и иврита

У меня есть база данных sqlite, в которую я хотел бы вставить значения на иврите.

Я продолжаю получать следующую ошибку:

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

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

runsql(u'INSERT в личные значения(%(ID)d,%(name)s)' % {'ID':1,'name':fabricate_hebrew_name()})

    def fabricate_hebrew_name():
        hebrew_names = [u'ירדן',u'יפה',u'תמי',u'ענת',u'רבקה',u'טלי',u'גינה',u'דנה',u'ימית',u'אלונה',u'אילן',u'אדם',u'חווה']
        return random.sample(names,1)[0].encode('utf-8')

примечание: runsql выполнение запроса к базе данных sqlite fabricate_hebrew_name() должно возвращать строку, которую можно использовать в моем SQL-запросе. Любая помощь горячо приветствуется.


person user340495    schedule 13.05.2010    source источник
comment
используйте 1_   -  person jfs    schedule 13.05.2010


Ответы (2)


Вы передаете сфабрикованные имена в параметр форматирования строки для строки Unicode. В идеале передаваемые таким образом строки также должны быть в формате Unicode.

Но Fabricate_hebrew_name не возвращает Unicode — он возвращает строку в кодировке UTF-8, что не одно и то же.

Итак, избавьтесь от вызова encode('utf-8') и посмотрите, поможет ли это.

Следующий вопрос заключается в том, какой тип ожидает runsql. Если он ожидает Unicode, нет проблем. Если ожидается строка в кодировке ASCII, у вас возникнут проблемы, поскольку иврит не является ASCII. В маловероятном случае ожидается строка в кодировке UTF-8, тогда пришло время ее преобразовать - после выполнения замены.

В другом ответе Игнасио Васкес-Абрамс предостерегает от интерполяции строк в запросах. Идея здесь заключается в том, что вместо подстановки строк с помощью оператора % вы обычно должны использовать параметризованный запрос и передавать ему строки на иврите в качестве параметров. Это может иметь некоторые преимущества в оптимизации запросов и защите от SQL-инъекций.

Пример

# -*- coding: utf-8 -*-
import sqlite3

# create db in memory
conn = sqlite3.connect(":memory:")
cur = conn.cursor()
cur.execute("CREATE TABLE personal ("
            "id INTEGER PRIMARY KEY,"
            "name VARCHAR(42) NOT NULL)")

# insert random name
import random
fabricate_hebrew_name = lambda: random.choice([
    u'ירדן',u'יפה',u'תמי',u'ענת', u'רבקה',u'טלי',u'גינה',u'דנה',u'ימית',
    u'אלונה',u'אילן',u'אדם',u'חווה'])

cur.execute("INSERT INTO personal VALUES("
            "NULL, :name)", dict(name=fabricate_hebrew_name()))
conn.commit()

id, name = cur.execute("SELECT * FROM personal").fetchone()
print id, name
# -> 1 אלונה
person Oddthinking    schedule 13.05.2010
comment
Эй, спасибо за ответ, он мне очень помог, и моя проблема теперь решена :) также я немного лучше понял идею этих типов строк на иврите. - person user340495; 13.05.2010
comment
Спасибо, Джей Ф. Я чувствую, что вы с Игнасио заслуживаете здесь львиную долю репутации. - person Oddthinking; 14.05.2010

Вы не должны кодировать вручную и не должны использовать интерполяцию строк для запросов .

person Ignacio Vazquez-Abrams    schedule 13.05.2010