Skip to content
This repository was archived by the owner on Apr 19, 2022. It is now read-only.

Conversation

@rotemvil1
Copy link

@rotemvil1 rotemvil1 commented Aug 13, 2019

The original NDB behavior when using default parameter is passing the default value inside datastore even when initiating a Model without the relevant. Currently, that doesn't happen. The entity is being saved without the default value which means that you can't query on it and worst than that, if you'll change the default value in the application level it'll affect on retro actively inserted queries.

Python 2.7 NDB example code:

from google.appengine.ext import ndb

class DefaultTest(ndb.Model):
    myCounter = ndb.IntegerProperty(required=False, default=20)

example = DefaultTest(id=123)
example.put()

In python 2.7 this entity will be saved with myCounter=20 in datastore while in python 3.7 this entity will be saved as an empty (containing only a key, missing myCounter aka missing all default properties that wasn't set explicitly in the Model init).

Python 37 NDB example code:

    class DefaultTest(ndb.Model):
        myCounter = ndb.IntegerProperty(required=False, default=20)

    example = DefaultTest(id=123)
    client.put(example)

Can be checked easily with this code:

client.get(client.key('DefaultTest', 123))['myCounter']

Which will get an exception in the Python 3.7 DS while in the 2.7 DS it'll get the correct value.

@rotemvil1 rotemvil1 changed the title Make default functionality the same as in the original datastore NDB. Make default property value functionality the same as in the original datastore NDB. Aug 14, 2019
@berlincode
Copy link
Owner

Hello and thank you for your report.

I totally agree with you that the behavior between python2 and python3.7 should be as close as possible.

The line you are changing should imho work exactly the same on both python2 and python3.7.

I've tried to reproduce your problem without success. On python2, python3.6 and python3.7 a non-set property with a default value is NOT stored! If you load the entity from the datastore ndb-orm shows you the default value from your model. This only works (of course) if you load your model class before fetching the entity. Maybe this might be the problem?

@rotemvil1
Copy link
Author

rotemvil1 commented Aug 19, 2019

Hey and thanks for the reply.

No offense but did you actually check my Python 2.7 code?
I've retried it now and the default parameter was actually STORED.
If you still can't reproduce that, I'll share a GCP project with you that you can test on it and see it's source code (which will contain this code + Flask..)
In the meanwhile, I'm adding an image from my GCP datastore (not emulator or any third party web UI that can interfere the results, real GCP datastore UI) after running my API in python 2.7:
Screen Shot 2019-08-19 at 2 08 10 PM

API code:

@app.route('/api/ds_default_test'`, methods=['GET'])
def ds_default_test():
    from google.appengine.ext import ndb

    class DefaultTest(ndb.Model):
        myCounter = ndb.IntegerProperty(required=False, default=20)

    example = DefaultTest(id=123)
    example.put()
    return '{}'

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants