2

I have a fairly simple ndb model that already exists has had instances created in the datastore. It looks something like this:

class ExampleModel(ndb.Model):
    property1 = ndb.StringProperty()
    property2 = ndb.StringProperty()

I want to add a created property to it, so that I can sort them by the time they were created.

class ExampleModel(ndb.Model):
    property1 = ndb.StringProperty()
    property2 = ndb.StringProperty()
    created = ndb.DateTimeProperty(auto_now_add=True)

When I do this, and try to query for the list of entities ordered by created, it only returns entities that have been created after updating the model definition.

things = ExampleModel.query().order(ExampleModel.created).fetch()

I have tried adding a default value to created, set to the epoch which is where I would like existing entities to be in the ordered list, but they still are not included in that ordered query. Is there any way to include them, or do I need to migrate the existing entities and set their created property explicitly?

Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
Michael Davis
  • 2,350
  • 2
  • 21
  • 29

2 Answers2

3

Based on this answer, it appears that you cannot do this.

They recommend setting the string property to the empty string. In your case, you can use some default date value. Your code must be smart enough to strip out this value. Perhaps something like this:

class ExampleModel(ndb.Model):
    DEFAULT_CREATED = datetime(2000, 1, 1)
    property1 = ndb.StringProperty()
    property2 = ndb.StringProperty()
    created = ndb.DateTimeProperty(auto_now_add=True)

    def created2(self):
        if self.created == DEFAULT_CREATED:
            return None
        else:
            return self.created

    def created2(self, value):
        if value is None:
            self.created = DEFAULT_CREATED
        else:
            self.value = value

You must of course update all null values in the datastore to the default value, but your client code is much simpler value = instance.created2() and instance.created2(value).

Community
  • 1
  • 1
dana
  • 17,267
  • 6
  • 64
  • 88
2

You will not be able to sort old entities on newly .created field - they will not appear in index used for sorting.

All you need is update existing entities according to new model definition. In the simplest form you can just get() and then immediately put() your items with .created property added to the model.

There is useful article in App Engine documentation - Updating Your Model Schema.

In the case there are lot of data need to be updated - consider using MapReduce.

Venya
  • 31
  • 1
  • 5