Say I have a class with two properties like so:
class Banana(ndb.Model):
is_delicious = ndb.BooleanProperty(default=True)
is_rotten = ndb.BooleanProperty(default=False)
A rotten Banana
entry cannot be delicious. How can I prevent saving a delicous, rotten banana to the datastore?
I can override the __init__
method as in this answer, but this does not prevent someone updating the banana to an impossible state.
The docs show a validator option but this doesn't work across fields.
How can I validate two fields of my model against one another to prevent saving an object in an incorrect state?
this does not prevent someone updating the banana to an impossible state.
Datastore provides almost zero schema enforcement on its own.
You could open the web console for your Datastore (https://console.cloud.google.com/datastore/entities) select an entity and start deleting properties off of it, even if you ndb
code has required=True
when defining the property
In the picture I could edit the field completed
to be a boolean instead of a date-time and then appengine would throw an exception everytime this entity is fetched via ndb
.
So I don't know where that leaves you. You could go the __init__
route
You could put the check in _pre_put_hook
:
class Banana(ndb.Model):
is_delicious = ndb.BooleanProperty(default=True)
is_rotten = ndb.BooleanProperty(default=False)
def _pre_put_hook(self):
if self.is_delicious and self.is_rotten:
raise Exception("A rotten Banana entry cannot be delicious")
You could have a ComputedProperty
do the check:
class Banana(ndb.Model):
is_delicious = ndb.BooleanProperty(default=True)
is_rotten = ndb.BooleanProperty(default=False)
def _is_valid(self):
if self.is_delicious and self.is_rotten:
raise Exception("A rotten Banana entry cannot be delicious")
return True
is_valid = ndb.ComputedProperty(lambda self: self._is_valid())
But all of these will only work when the db is being access by your ndb
code