0

私はpython dicts(utf8コンテンツ)を保存するためにsqlite3テーブルを使用しており、シリアル化はJSONで行われます。python2.7 では正常に動作しますが、3.3 では失敗します。

スキーマ:

CREATE TABLE mytable
  (id INTEGER, book TEXT NOT NULL, d JSON NOT NULL, priority INTEGER NOT NULL DEFAULT(3), 
   PRIMARY KEY (id, book))

値を挿入するとき、dict は でシリアル化されjson.dumps(d)ます。障害のある部分は、以前に保存された値を取得しています。

import sys
import sqlite3
import json

filename = 'mydb.db'
sqlite3.register_converter('JSON', json.loads)
conn = sqlite3.connect(filename, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
c = conn.cursor()
c.execute('''SELECT book, id, d, priority FROM mytable''')
print(c.fetchall())

上記のスクリプトは、python2.7 で実行すると正常に動作します。ただし、3.3 を使用すると TypeError が発生します。

Traceback (most recent call last):
  File "tests/py3error_debug.py", line 15, in <module>
    c.execute('''SELECT book, id, d, priority FROM mytable''')
  File "/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/lib/python3.3/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/python3/3.3.2/Frameworks/Python.framework/Versions/3.3/lib/python3.3/json/decoder.py", line 352, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
TypeError: can't use a string pattern on a bytes-like object

2.7 と 3.3 の JSON モジュール (特に に関して) の本質的な違いを見つけることができずjson.loads、アイデアが不足しています。

4

1 に答える 1

1

Python 3 json モジュールのドキュメントによると:

json モジュールは、bytes オブジェクトではなく、常にstrオブジェクトを生成します。...

Python 3 sqlite3.register_converter ドキュメントによると:

データベースのバイト文字列をカスタム Python 型に変換する呼び出し可能オブジェクトを登録します。...

bytesstring json をロードしようとすると、TypeError が発生します。

>>> json.loads('"0"')
'0'
>>> json.loads(b'"0"')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.3/json/__init__.py", line 319, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.3/json/decoder.py", line 352, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
TypeError: can't use a string pattern on a bytes-like object

bytes.decodejson.loadsを使用して呼び出す前に、バイトを str に変換する必要があります。

sqlite3.register_converter('JSON', lambda x: json.loads(x.decode('utf-8')))
于 2013-08-24T02:26:07.343 に答える