Why required and default are mutally exclusive in ndb?
Asked Answered
D

2

12

In old google appengine datastore API "required" and "default" could be used together for property definitions. Using ndb I get a

ValueError: repeated, required and default are mutally exclusive.

Sample code:

from google.appengine.ext import ndb
from google.appengine.ext import db

class NdbCounter(ndb.Model):
    # raises ValueError
    count = ndb.IntegerProperty(required=True, default=1)

class DbCounter(db.Model):
    # Doesn't raise ValueError
    count = db.IntegerProperty(required=True, default=1)

I want to instantiate a Counter without having to specify a value. I also want to avoid someone to override that value to None. The example above is constructed. I could probably live without a required attribute and instead add an increment() method. Still I don't see the reason why required and default are mutually exclusive.

Is it a bug or a feature?

Depressant answered 9/1, 2013 at 8:30 Comment(0)
K
12

I think you are right. Perhaps I was confused when I write that part of the code. It makes sense that "required=True" means "do not allow writing the value None" so it should be possible to combine this with a default value. Please file a feature request in the NDB tracker: http://code.google.com/p/appengine-ndb-experiment/issues/list

Note that for repeated properties things are more complicated, to repeated will probably continue to be incompatible with either required or default, even if the above feature is implemented.

Kaden answered 10/1, 2013 at 17:36 Comment(1)
Thanks. I've created the issue code.google.com/p/appengine-ndb-experiment/issues/detail?id=236Depressant
M
1

I'm not sure what was intended, here is the "explanation" from appengine.ext.ndb.model.py

The repeated, required and default options are mutually exclusive: a repeated property cannot be required nor can it specify a default value (the default is always an empty list and an empty list is always an allowed value), and a required property cannot have a default.

Notice the explanation and behavior changed (around Jan 1, 2024 with the release 1.0.10 (release for 1.8.9 SDK)). See the latest appengine.ext.ndb.model.py:

The repeated and required/default options are mutually exclusive: a repeated property cannot be required nor can it specify a default value (the default is always an empty list and an empty list is always an allowed value), but a required property can have a default.

Beware that ndb has some other really annoying behaviour ( Text>500 Bytes not possible without monkey-patching the expando-model, filtering by .IN( [] ) raises exception, ..). So unless you need the speed-improvements by its caching you should consider staying with ext.db at the moment.

Moreira answered 9/1, 2013 at 9:13 Comment(2)
So this seems to be a conceptual bug. I don't see a reason for this restriction. The restriction should be that default can not be None if required=True.Depressant
to me it sort of makes sense as it is. If you require a value then why bother to specify a default also as you might as well not have required = True in that case (as if you do nothing else but create and save the model it'll work as it has a default). The required = True is a reminder to me that if I try and save this model without a value in that field it'll fail, whereas if I supply a default it'll never fail to save and that, for me, is the point of required.Hawaiian

© 2022 - 2024 — McMap. All rights reserved.