-
Notifications
You must be signed in to change notification settings - Fork 0
/
db_util.py
executable file
·80 lines (64 loc) · 2.34 KB
/
db_util.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
#!/usr/bin/python2.4
#
# Copyright 2009 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Datastore utilities."""
__author__ = '[email protected] (Matt Frantz)'
import logging
try:
from google.appengine.ext import db
except ImportError:
from google3.apphosting.ext import db
# Allow independent control of the logging from this module.
logger = logging.getLogger(__file__)
logger.setLevel(logging.INFO)
def ModelAsDict(model_class, model):
"""Extracts db.Model properties as a dict.
Args:
model_class: db.Model subclass
model: db.Model object
Returns:
Dict with attribute names as keys and attribute values as values.
"""
props = {}
for prop in model_class.properties().keys() + model.dynamic_properties():
try:
props[prop] = SafelyDereference(model, prop)
except db.Error:
# Sometimes, a reference attribute will fail to load because its
# referent has been deleted. Handle this gracefully.
logger.warn('Unable to extract %s.%s from %r',
model_class.kind(), prop, model)
logger.debug('ModelAsDict %s = %r', model_class.kind(), props)
return props
def SafelyDereference(model, property_name):
"""Safely dereference a property that may be a Reference.
Args:
model: Model instance (db.Model)
property_name: Name of the property, possibly a Reference (str)
Returns:
Referent object, or None if it was a Reference that would not resolve.
Raises:
db.Error: If anything other than dereferencing errors occur.
"""
try:
return getattr(model, property_name)
except db.Error, e:
if 'ReferenceProperty failed to be resolved' in str(e):
model_name = model.__class__.kind()
logging.error('Could not dereference "%s" property on %s model %s',
property_name, model_name, model.key())
return None
else:
raise