From ce43a2f3ceac469d6d01aa41be1a057b43af81e1 Mon Sep 17 00:00:00 2001 From: bobwanglyft <33230720+bobwanglyft@users.noreply.github.com> Date: Wed, 14 Oct 2020 15:00:21 -0700 Subject: [PATCH] Allow VersionAttribute to operate on items with a version of zero (#869) --- pynamodb/models.py | 2 +- tests/test_model.py | 54 +++++++++++++++++++++++++++++++++++++++++++++ tox.ini | 2 +- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/pynamodb/models.py b/pynamodb/models.py index 1d03f3e9e..9468b5346 100644 --- a/pynamodb/models.py +++ b/pynamodb/models.py @@ -936,7 +936,7 @@ def _handle_version_attribute(self, serialized_attributes, actions=None): version_attribute = self.get_attributes()[self._version_attribute_name] version_attribute_value = getattr(self, self._version_attribute_name) - if version_attribute_value: + if version_attribute_value is not None: version_condition = version_attribute == version_attribute_value if actions: actions.append(version_attribute.add(1)) diff --git a/tests/test_model.py b/tests/test_model.py index c30b731b1..fde546b1d 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -3076,6 +3076,60 @@ def test_model_version_attribute_save(self): deep_eq(args, params, _assert=True) + def test_model_version_attribute_save_with_initial_version_zero(self): + self.init_table_meta(VersionedModel, VERSIONED_TABLE_DATA) + item = VersionedModel('test_user_name', email='test_user@email.com', version=0) + + with patch(PATCH_METHOD) as req: + req.return_value = {} + item.save() + args = req.call_args[0][1] + params = { + 'Item': { + 'name': { + 'S': 'test_user_name' + }, + 'email': { + 'S': 'test_user@email.com' + }, + 'version': { + 'N': '1' + }, + }, + 'ReturnConsumedCapacity': 'TOTAL', + 'TableName': 'VersionedModel', + 'ConditionExpression': '#0 = :0', + 'ExpressionAttributeNames': {'#0': 'version'}, + 'ExpressionAttributeValues': {':0': {'N': '0'}} + } + + deep_eq(args, params, _assert=True) + item.version = 1 + item.name = "test_new_username" + item.save() + args = req.call_args[0][1] + + params = { + 'Item': { + 'name': { + 'S': 'test_new_username' + }, + 'email': { + 'S': 'test_user@email.com' + }, + 'version': { + 'N': '2' + }, + }, + 'ReturnConsumedCapacity': 'TOTAL', + 'TableName': 'VersionedModel', + 'ConditionExpression': '#0 = :0', + 'ExpressionAttributeNames': {'#0': 'version'}, + 'ExpressionAttributeValues': {':0': {'N': '1'}} + } + + deep_eq(args, params, _assert=True) + def test_version_attribute_increments_on_update(self): self.init_table_meta(VersionedModel, VERSIONED_TABLE_DATA) item = VersionedModel('test_user_name', email='test_user@email.com') diff --git a/tox.ini b/tox.ini index 00cb5f504..41e682035 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36,py37,pypy,pypy3 +envlist = py36,py37,py38,pypy,pypy3 [testenv] deps = -rrequirements-dev.txt