-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmodels.py
54 lines (41 loc) · 1.91 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
"""App Engine datastore model base classes, properties, and utilites.
"""
from google.cloud import ndb
from oauth_dropins.webutil.util import json_dumps, json_loads
# 1MB limit: https://cloud.google.com/datastore/docs/concepts/limits
# use this to check an entity's size:
# len(entity._to_pb().Encode())
MAX_ENTITY_SIZE = 1 * 1000 * 1000
class StringIdModel(ndb.Model):
"""An :class:`ndb.Model` class that requires a string id."""
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 :class:`ndb.TextProperty` instead of :class:`ndb.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
Duplicated in arroba:
https://github.com/snarfed/arroba/blob/main/arroba/ndb_storage.py
"""
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)
class ComputedJsonProperty(JsonProperty, ndb.ComputedProperty):
"""Custom :class:`ndb.ComputedProperty` for JSON values that stores them as
strings.
...instead of like :class:`ndb.StructuredProperty`, with "entity" type,
which bloats them unnecessarily in the datastore.
"""
def __init__(self, *args, **kwargs):
kwargs['indexed'] = False
super().__init__(*args, **kwargs)