suresh
suresh

Reputation: 1

Saving object creation datetime using Pynamodb

I want to update the creation_datetime only when a new object is created and update the last_update_datetime on every update while using the save method. default_for_new is updating time even when the existing object is updating. any alternatives?

below is the sample code I tried

from pynamodb.models import Model
from pynamodb.attributes import  UTCDateTimeAttribute

def current_datetime():
    from datetime import datetime
    return datetime.now()


class AbstractDateTimeModel(Model):
    creation_datetime = UTCDateTimeAttribute(default_for_new=current_datetime)
    last_update_datetime = UTCDateTimeAttribute(default=current_datetime)

    class Meta(object):
        abstract = True

Upvotes: 0

Views: 1928

Answers (2)

martasd
martasd

Reputation: 125

For the original abstract model the overridden function would be:

def update(self, actions=[], condition=None, add_version_condition=True):
    actions.append(AbstractDateTimeModel.updateDateTime.set(get_current_time_utc()))     
    Model.update(self, actions, condition) 

Upvotes: 0

Anuradha Wickramarachi
Anuradha Wickramarachi

Reputation: 329

For versions < 6.0.0

The best way you can do this is overriding the update method of your Object class. This is an example:

from datetime import datetime, timezone

from pynamodb.models import Model
from pynamodb.settings import OperationSettings
from pynamodb.attributes import UTCDateTimeAttribute, UnicodeAttribute, NumberAttribute


def get_current_time_utc():
        return datetime.now(timezone.utc)


class SalesItem(Model):
    class Meta:
        table_name = 'monthlySales'

    id = UnicodeAttribute(hash_key=True)
    month= UnicodeAttribute()
    sales= NumberAttribute()
    createDateTime = UTCDateTimeAttribute(default_for_new=get_current_time_utc)
    updateDateTime = UTCDateTimeAttribute(default_for_new=get_current_time_utc)


    # overriding the method to add timestamp on update
    def update(self, actions=[], condition=None, settings=OperationSettings.default):
        actions.append(SalesItem.updateDateTime.set(get_current_time_utc()))
        Model.update(self, actions, condition, settings)

We just need to append an action to the actions list asking the timestamp update. Then call the parent's update method. Now you can forget about the timestamps and use the update method as you would.

item = SalesItem.get('pynamodb-test')
# do your updates here
item.update(actions=[
    SalesItem.sales.set(item.sales + 1)
])

For v6.0.0

As per the release notes, OperationSettings has been removed and therefore the overriding function will be:

# overriding the method to add timestamp on update
def update(self, actions=[], condition=None):
    actions.append(SalesItem.updateDateTime.set(get_current_time_utc()))
    Model.update(self, actions, condition)

Upvotes: 3

Related Questions