Improve the data-type conversion for JSON values.

This commit is contained in:
Charles Leifer
2019-08-01 09:58:28 -05:00
parent ba57ccc7ab
commit ef27f0209a
2 changed files with 25 additions and 3 deletions
+5 -2
View File
@@ -3,6 +3,7 @@ Collection of postgres-specific extensions, currently including:
* Support for hstore, a key/value type storage
"""
import json
import logging
import uuid
@@ -277,18 +278,19 @@ class HStoreField(IndexedFieldMixin, Field):
class JSONField(Field):
field_type = 'JSON'
_json_datatype = 'json'
def __init__(self, dumps=None, *args, **kwargs):
if Json is None:
raise Exception('Your version of psycopg2 does not support JSON.')
self.dumps = dumps
self.dumps = dumps or json.dumps
super(JSONField, self).__init__(*args, **kwargs)
def db_value(self, value):
if value is None:
return value
if not isinstance(value, Json):
return Json(value, dumps=self.dumps)
return Cast(self.dumps(value), self._json_datatype)
return value
def __getitem__(self, value):
@@ -307,6 +309,7 @@ def cast_jsonb(node):
class BinaryJSONField(IndexedFieldMixin, JSONField):
field_type = 'JSONB'
_json_datatype = 'jsonb'
__hash__ = Field.__hash__
def contains(self, other):
+20 -1
View File
@@ -617,7 +617,8 @@ class BaseJsonFieldTestCase(object):
table = self.M._meta.table_name
self.assertSQL(j, (
'SELECT "t1"."id", "t1"."data" '
'FROM "%s" AS "t1" WHERE ("t1"."data" = ?)') % table)
'FROM "%s" AS "t1" WHERE ("t1"."data" = CAST(? AS %s))')
% (table, self.M.data._json_datatype))
j = (self.M
.select()
@@ -938,6 +939,24 @@ class TestBinaryJsonField(BaseJsonFieldTestCase, ModelTestCase):
self.assertEqual(BJson.select().count(), 1)
@skip_unless(JSON_SUPPORT, 'json support unavailable')
class TestBinaryJsonFieldBulkUpdate(ModelTestCase):
database = db
requires = [BJson]
def test_binary_json_field_bulk_update(self):
b1 = BJson.create(data={'k1': 'v1'})
b2 = BJson.create(data={'k2': 'v2'})
b1.data['k1'] = 'v1-x'
b2.data['k2'] = 'v2-y'
BJson.bulk_update([b1, b2], fields=[BJson.data])
b1_db = BJson.get(BJson.id == b1.id)
b2_db = BJson.get(BJson.id == b2.id)
self.assertEqual(b1_db.data, {'k1': 'v1-x'})
self.assertEqual(b2_db.data, {'k2': 'v2-y'})
class TestIntervalField(ModelTestCase):
database = db
requires = [Event]