json - Python dict deserialization works in python2.7, fails in 3.3 -
i'm using sqlite3 table store python dicts (utf8 content) , serialization done json. works fine in python2.7 fails in 3.3.
schema:
create table mytable (id integer, book text not null, d json not null, priority integer not null default(3), primary key (id, book))
when inserting values, dict serialized json.dumps(d)
. faulty part retrieving saved values.
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 mytable''') print(c.fetchall())
the above script works fine when executed python2.7. however, using 3.3 typeerror occures:
traceback (most recent call last): file "tests/py3error_debug.py", line 15, in <module> c.execute('''select book, id, d, priority 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 string pattern on bytes-like object
i can't spot essential difference between 2.7 , 3.3 json modules (especially regarding json.loads
) , i'm running out of ideas.
according python 3 json module documentation:
the json module produces str objects, not bytes objects. ...
according python 3 sqlite3.register_converter documentation:
registers callable convert bytestring database custom python type. ...
if try load 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 string pattern on bytes-like object
you should convert bytes str before call json.loads
using bytes.decode.
sqlite3.register_converter('json', lambda x: json.loads(x.decode('utf-8')))
Comments
Post a Comment