decurgia
decurgia

Reputation: 111

auto field values in ndb.StructuredProperty

I want to store locations in google's datastore. Each entry shall have got 'sys'-fields, which shall contain information set by the datastore. I've got the class model below and the WebService JSON request/response looks ok, but I have to set the values manually. It looks like auto_current_user_add, auto_now_add, auto_current_user and auto_now does not trigger.

from google.appengine.ext import ndb
from endpoints_proto_datastore.ndb import EndpointsModel


class Created(EndpointsModel):
    by = ndb.UserProperty(auto_current_user_add=True)
    on = ndb.DateTimeProperty(auto_now_add=True)


class Updated(EndpointsModel):
    by = ndb.UserProperty(auto_current_user=True)
    on = ndb.DateTimeProperty(auto_now=True)


class Sys(EndpointsModel):
    created = ndb.StructuredProperty(Created)
    updated = ndb.StructuredProperty(Updated)


class Location(EndpointsModel):
    name = ndb.StringProperty(required=True)
    description = ndb.TextProperty()
    address = ndb.StringProperty()
    sys = ndb.StructuredProperty(Sys)

When I submit a create request (location.put()) I get the following response:

{
    "id": "4020001",
    "name": "asdf"
}

When I set it manually using:

location.sys = Sys(created=Created(on=datetime.datetime.now(),
                                   by=current_user),
                   updated=Updated(on=datetime.datetime.now(),
                                   by=current_user))
location.put()

I get the expected result:

{
 "id": "4020002",
 "name": "asdf",
 "sys": {
  "created": {
   "by": {
    "auth_domain": "gmail.com",
    "email": "decurgia@XYZ"
   },
   "on": "2015-01-27T16:05:41.465497"
  },
  "updated": {
   "by": {
    "auth_domain": "gmail.com",
    "email": "decurgia@XYZ"
   },
   "on": "2015-01-27T16:05:41.465577"
  }
 }
}

How can I get those fields (sys.created.on, sys.created.by, sys.updated.on, sys.updated.by) automatically set?

Upvotes: 1

Views: 335

Answers (1)

Brent Washburne
Brent Washburne

Reputation: 13158

In my limited work with StructuredProperty, I found it to be slower and more difficult to use than simply inserting the properties directly into the model. NDB seems to store those properties separately and perform a "join" when retrieving them. My recommendation is to use a "flat" model:

class Location(EndpointsModel):
    name = ndb.StringProperty(required=True)
    description = ndb.TextProperty()
    address = ndb.StringProperty()
    created_by = ndb.UserProperty(auto_current_user_add=True)
    created_on = ndb.DateTimeProperty(auto_now_add=True)
    updated_by = ndb.UserProperty(auto_current_user=True)
    updated_on = ndb.DateTimeProperty(auto_now=True)

This should cause the auto_ properties to be triggered automatically.

Upvotes: 1

Related Questions