-
Notifications
You must be signed in to change notification settings - Fork 4
/
object_property.py
97 lines (77 loc) · 3.22 KB
/
object_property.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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# From http://kovshenin.com/archives/app-engine-python-objects-in-the-google-datastore/
from google.appengine.ext import db
import pickle
# Use this property to store objects.
class ObjectProperty(db.BlobProperty):
def validate(self, value):
try:
result = pickle.dumps(value)
return value
except pickle.PicklingError, e:
return super(ObjectProperty, self).validate(value)
def get_value_for_datastore(self, model_instance):
result = super(ObjectProperty, self).get_value_for_datastore(model_instance)
result = pickle.dumps(result)
return db.Blob(result)
def make_value_from_datastore(self, value):
try:
value = pickle.loads(str(value))
except:
pass
return super(ObjectProperty, self).make_value_from_datastore(value)
class UnvalidatedObjectProperty(ObjectProperty):
def validate(self, value):
# pickle.dumps can be slooooooow,
# sometimes we just want to trust that the item is pickle'able.
return value
class TsvProperty(db.UnindexedProperty):
'''
An alternative to StringListProperty that serializes lists using a simple
tab-separated format. This is much faster than StringPropertyList, however
elements with tabs are not permitted.
'''
data_type = list
def __init__(self, default=None, **kwds):
if default is None:
default = []
super(TsvProperty, self).__init__(default=default, **kwds)
def get_value_for_datastore(self, model_instance):
value = super(TsvProperty, self).get_value_for_datastore(model_instance)
return db.Text("\t".join(value))
def make_value_from_datastore(self, value):
return self.str_to_tsv(value)
@staticmethod
def str_to_tsv(value):
return value.split("\t") if value else []
def empty(self, value):
"""Is list property empty.
[] is not an empty value.
Returns:
True if value is None, else false.
"""
return value is None
def default_value(self):
"""Default value for list.
Because the property supplied to 'default' is a static value,
that value must be shallow copied to prevent all fields with
default values from sharing the same instance.
Returns:
Copy of the default value.
"""
return list(super(TsvProperty, self).default_value())
# the following properties are useful for migrating StringListProperty to
# the faster TsvProperty
class TsvCompatStringListProperty(db.StringListProperty):
'A StringListProperty that can also lists serialized as read tab separated strings'
def make_value_from_datastore(self, value):
if isinstance(value, list):
return super(TsvCompatStringListProperty, self).make_value_from_datastore(value)
else:
return TsvProperty.str_to_tsv(value)
class StringListCompatTsvProperty(TsvProperty):
'A TsvProperty that can also read lists serialized as native Python lists'
def make_value_from_datastore(self, value):
if isinstance(value, list):
return value
else:
return super(StringListCompatTsvProperty, self).make_value_from_datastore(value)