Last active
August 29, 2015 14:05
-
-
Save jzerbe/466ddec827cd766313ed to your computer and use it in GitHub Desktop.
PolyModel for ever-more-specific selection information instead of a sparse data model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from google.appengine.ext import ndb | |
from google.appengine.ext.ndb import polymodel | |
class SelectionBinder(polymodel.PolyModel): | |
""" | |
Base class for selecting content. | |
https://developers.google.com/appengine/docs/python/ndb/polymodelclass | |
All selections are at the binder level or more specific. | |
""" | |
# the binder in which the selection resides | |
binder_id = ndb.StringProperty(indexed=True, required=True) | |
# last time the entity was put | |
last_modified = ndb.DateTimeProperty(auto_now=True) | |
# every selection is for tying some metadata to some content. | |
# key.urlsafe() representation of Annotation.key | |
# https://developers.google.com/appengine/docs/python/ndb/keyclass#Key_urlsafe | |
annotation_key = ndb.StringProperty(indexed=True, required=True) | |
class SelectionDoc(SelectionBinder): | |
""" | |
Selecting inside of a particular document. | |
""" | |
document_id = ndb.StringProperty(indexed=True, required=True) | |
class SelectionPage(SelectionDoc) | |
page_id = ndb.StringProperty(indexed=True, required=True) | |
class SelectionRegion(SelectionPage): | |
""" | |
A region can be a paragraph, chart, some object inside of a page. | |
""" | |
region_id = ndb.StringProperty(indexed=True, required=True) | |
class SelectionText(SelectionRegion): | |
""" | |
When the parent region is a paragraph, the user is selecting some text. | |
""" | |
start_index = ndb.IntegerProperty(indexed=False, required=True) | |
end_index = ndb.IntegerProperty(indexed=False, required=True) | |
class SelectionXY(SelectionRegion): | |
""" | |
Put a point over a region at an X/Y offset from the top-left. | |
Only works with static content. | |
""" | |
position_x = ndb.IntegerProperty(indexed=False, required=True) | |
position_y = ndb.IntegerProperty(indexed=False, required=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from google.appengine.ext import ndb | |
class SparseModel(ndb.Model): | |
def _prepare_for_put(self): | |
if self._properties: | |
# store delete work for after read is done | |
keys_to_remove = [] | |
for key, value in self._properties.iteritems(): | |
if value is None: | |
keys_to_remove.append(key) | |
# delete properties with None | |
for key in keys_to_remove: | |
del self._properties[key] | |
# finally dig into nested properties | |
for prop in self._properties.itervalues(): | |
prop._prepare_for_put(self) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
instead of dropping all
None
columns from existence on databaseput
via a hack, one can be smart about instantiating entities at the appropriate specificity and reap the rewards of inheritance