From c5cf0610643f4a33455aad6e58d85b6b16fb58c4 Mon Sep 17 00:00:00 2001 From: Ryan Barrett Date: Fri, 24 Feb 2023 07:07:46 -0600 Subject: [PATCH] add fork of ndb's JsonProperty that works in the datastore web console https://github.com/googleapis/python-ndb/issues/874#issuecomment-1442753255 --- models.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/models.py b/models.py index 523d248..d79247c 100644 --- a/models.py +++ b/models.py @@ -1,7 +1,9 @@ -"""App Engine datastore model base classes and utilites. +"""App Engine datastore model base classes, properties, and utilites. """ from google.cloud import ndb +from oauth_dropins.webutil.util import json_dumps, json_loads + class StringIdModel(ndb.Model): """An ndb model class that requires a string id.""" @@ -9,3 +11,24 @@ def put(self, *args, **kwargs): """Raises AssertionError if string id is not provided.""" assert self.key and self.key.string_id(), 'string id required but not provided' return super(StringIdModel, self).put(*args, **kwargs) + + +class JsonProperty(ndb.TextProperty): + """Fork of ndb's that subclasses TextProperty instead of BlobProperty. + + This makes values show up as normal, human-readable, serialized JSON in the + web console. + https://github.com/googleapis/python-ndb/issues/874#issuecomment-1442753255 + """ + def _validate(self, value): + if not isinstance(value, dict): + raise TypeError("JSON property must be a dict") + + def _to_base_type(self, value): + as_str = json_dumps(value, separators=(",", ":"), ensure_ascii=True) + return as_str.encode("ascii") + + def _from_base_type(self, value): + if not isinstance(value, str): + value = value.decode("ascii") + return json_loads(value)