3

ヘブライ語で値を挿入したいsqliteデータベースがあります

次のエラーが発生し続けます:

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

私のコードは次のとおりです:

runsql(u'INSERT into personal values(%(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')

注: runsqlsqlite データベースでクエリを実行する fabricate_hebrew_name()と、SQL クエリで使用できる文字列が返されるはずです。どんな助けでも大歓迎です。

4

2 に答える 2

4

製造された名前を Unicode 文字列の文字列フォーマット パラメータに渡しています。理想的には、この方法で渡される文字列も Unicode である必要があります。

しかし、fabricate_hebrew_name は Unicode を返していません。同じではない UTF-8 でエンコードされた文字列が返されます。

したがって、encode('utf-8') の呼び出しを取り除き、それが役立つかどうかを確認してください。

次の質問は、runsql が期待する型です。Unicode を想定している場合は問題ありません。ASCII でエンコードされた文字列を想定している場合、ヘブライ語は ASCII ではないため、問題が発生します。まれに、UTF-8 でエンコードされた文字列が想定されている場合は、置換が完了した後で変換します。

別の回答では、Ignacio Vazquez-Abrams がクエリでの文字列補間に対して警告しています。ここでの概念は、% 演算子を使用して文字列の置換を行う代わりに、通常はパラメーター化されたクエリを使用し、ヘブライ語の文字列をパラメーターとして渡す必要があるということです。これにより、クエリの最適化と 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 אלונה
于 2010-05-13T16:46:18.593 に答える
2

手動でエンコードしたり、クエリに文字列補間を使用したりしないでください。

于 2010-05-13T16:37:38.683 に答える