3

次の問題の解き方を知っている人はいますか?

現在、私はこのコードを使用しています:

def databasedump(request):
    # Convert file existing_db.db to SQL dump file dump.sql
    con = sqlite3.connect('database.sqlite')
    with open('dump.sql', 'w') as f:  
        for line in con.iterdump():
            f.write('%s\n' % line)

そして、私はこのエラーを受け取ります:

例外の種類:
UnicodeEncodeError

例外値:
'ascii' コーデックは位置 112 の文字 u'\xe9' をエンコードできません: 序数が範囲内にありません (128)

エンコード/デコードできなかった文字列は次のとおりです: (Arivé、PAK

ご検討いただきありがとうございます。

4

1 に答える 1

3

sqlite3ダンプ コードにバグがあり、Python バグ トラッカーでissue 15019として追跡されています。

これを修正するには、sqlite3/dump.pyファイルを編集して先頭に次の行を追加します。

from __future__ import unicode_literals

次のコマンドを実行して、ファイルを見つけます。

python -c 'import sqlite3.dump; print sqlite3.dump.__file__.rstrip("c")'

.iterdump()メソッドから返される Unicode 値をエンコードするために、コードを記述する行を調整する必要があります。

with open('dump.sql', 'w') as f:  
    for line in con.iterdump():
        f.write('%s\n' % line.encode('utf8'))

Python 標準ライブラリのソース ファイルを編集するのが面倒な場合は、代わりに次の (修正および短縮された) 関数を使用してください。

def iterdump(connection):
    cu = connection.cursor()
    yield(u'BEGIN TRANSACTION;')

    q = """
        SELECT "name", "type", "sql"
        FROM "sqlite_master"
            WHERE "sql" NOT NULL AND
            "type" == 'table'
        """
    schema_res = cu.execute(q)
    for table_name, type, sql in sorted(schema_res.fetchall()):
        if table_name == 'sqlite_sequence':
            yield(u'DELETE FROM "sqlite_sequence";')
        elif table_name == 'sqlite_stat1':
            yield(u'ANALYZE "sqlite_master";')
        elif table_name.startswith('sqlite_'):
            continue
        else:
            yield(u'{0};'.format(sql))

        table_name_ident = table_name.replace('"', '""')
        res = cu.execute('PRAGMA table_info("{0}")'.format(table_name_ident))
        column_names = [str(table_info[1]) for table_info in res.fetchall()]
        q = """SELECT 'INSERT INTO "{0}" VALUES({1})' FROM "{0}";""".format(
            table_name_ident,
            ",".join("""'||quote("{0}")||'""".format(col.replace('"', '""')) for col in column_names))
        query_res = cu.execute(q)
        for row in query_res:
            yield(u"{0};".format(row[0]))

    q = """
        SELECT "name", "type", "sql"
        FROM "sqlite_master"
            WHERE "sql" NOT NULL AND
            "type" IN ('index', 'trigger', 'view')
        """
    schema_res = cu.execute(q)
    for name, type, sql in schema_res.fetchall():
        yield(u'{0};'.format(sql))

    yield(u'COMMIT;')

上記を次のように使用します。

con = sqlite3.connect('database.sqlite')
with open('dump.sql', 'w') as f:  
    for iterdump(con):
        f.write('%s\n' % line.encode('utf8'))
于 2012-11-15T09:43:33.357 に答える