How to create a read-only model attribute in pynamodb?

460 Views Asked by At

I'm working on a model which implements a read-only attribute with a simple hack:

from pynamodb.models import Model


class MyModel(Model):
    […]
    updated_at = UTCDateTimeAttribute()

    def save(self):
        self.updated_at = datetime.now(timezone.utc)
        return super().save()

With this hack the user needs to provide updated_at when creating an instance, even though the value will be ignored.

That immediate issue could be solved by updated_at = UTCDateTimeAttribute(null=True), but now the model signals that updated_at might not be part of the response, which is not the case.

Basically, how can I signal to the user that they cannot provide a value for a field (ideally trying to set updated_at should result in an error), but that every instance of this model will have a value for this field?

1

There are 1 best solutions below

2
On

You can override the __init__ method of MyModel to check for the presence of updated_at in passed attributes, and raise an Exception if it is present:

class MyModel(Model):
    def __init__(self, hash_key=None, range_key=None, _user_instantiated=True, **attributes):
        if "updated_at" in attributes.keys():
            raise IllegalArgumentException
        super().__init__(
            hash_key=hash_key,
            range_key=range_key,
            _user_instantiated=_user_instantiated,
            **attributes,
        )

Similar updates to the save and update methods that check that the object that is being saved has an identical updated_at value to the object in the DB should be sufficient for the requirements above.