From 220424745408c98e825e86b4e61fedddfb6d1acd Mon Sep 17 00:00:00 2001 From: bpsoos Date: Wed, 24 Jul 2024 14:26:54 +0200 Subject: [PATCH 1/4] adds integration test for manual update version attribute in transaction --- .../test_transaction_integration.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/integration/test_transaction_integration.py b/tests/integration/test_transaction_integration.py index e247fd85..48512d61 100644 --- a/tests/integration/test_transaction_integration.py +++ b/tests/integration/test_transaction_integration.py @@ -428,3 +428,51 @@ def test_transaction_write_with_version_attribute_condition_failure(connection): assert len(exc_info.value.cancellation_reasons) == 1 assert exc_info.value.cancellation_reasons[0].code == 'ConditionalCheckFailed' assert Foo.Meta.table_name in exc_info.value.cause.MSG_TEMPLATE + + +@pytest.mark.ddblocal +def test_transaction_write_without_version_attribute_condition(connection): + foo = Foo(22) + foo.save() + assert Foo.get(22).version == 1 + foo.star = 'initial_update' + foo.save() + assert Foo.get(22).version == 2 + + foo2 = Foo(22) # try to update a field without getting the item first + + with TransactWrite(connection=connection) as transaction: + transaction.update( + foo2, + actions=[ + Foo.star.set('birdistheword'), + ], + add_version_condition=False, + ) + + foo_updated = Foo.get(22) + assert foo_updated.version == 2 # should not modify the version + assert foo_updated.star == 'birdistheword' + + +@pytest.mark.ddblocal +def test_transaction_write_increment_version_without_version_attribute_condition(connection): + foo = Foo(23) + foo.save() + assert Foo.get(23).version == 1 + + foo2 = Foo(23) + + with TransactWrite(connection=connection) as transaction: + transaction.update( + foo2, + actions=[ + Foo.star.set('birdistheword'), + Foo.version.set(Foo.version + 1), + ], + add_version_condition=False, + ) + + foo_updated = Foo.get(23) + assert foo_updated.version == 2 + assert foo_updated.star == 'birdistheword' From b8f57c9cb3671020be3ca4624786fad53c44e5ce Mon Sep 17 00:00:00 2001 From: bpsoos Date: Wed, 24 Jul 2024 14:44:26 +0200 Subject: [PATCH 2/4] adds model update with version attribute integration test --- tests/integration/model_integration_test.py | 59 +++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tests/integration/model_integration_test.py b/tests/integration/model_integration_test.py index 9a54cccc..c77af5ca 100644 --- a/tests/integration/model_integration_test.py +++ b/tests/integration/model_integration_test.py @@ -142,3 +142,62 @@ class Meta: version_invalid = VersionAttribute() assert str(e.value) == 'The model has more than one Version attribute: version, version_invalid' + + +@pytest.mark.ddblocal +def test_update_model_with_version_attribute_without_get(ddb_url): + class TestModel(Model): + """ + A model for testing + """ + class Meta: + region = 'us-east-1' + table_name = 'pynamodb-ci' + host = ddb_url + forum = UnicodeAttribute(hash_key=True) + scores = NumberSetAttribute() + version = VersionAttribute() + + if TestModel.exists(): + TestModel.delete_table() + TestModel.create_table(read_capacity_units=1, write_capacity_units=1, wait=True) + + obj = TestModel('1') + obj.save() + assert TestModel.get('1').version == 1 + obj.scores = 1 + obj.save() + assert TestModel.get('1').version == 2 + + obj_by_key = TestModel('1') # try to update item without getting it first + obj_by_key.update( + actions=[ + TestModel.scores.set(2), # no version increment + ], + add_version_condition=False + ) + updated_obj = TestModel.get('1') + assert updated_obj.scores == 2 + assert updated_obj.version == 2 + + + obj_2 = TestModel('2') + obj_2.save() + assert TestModel.get('2').version == 1 + obj_2.scores = 1 + obj_2.save() + assert TestModel.get('2').version == 2 + + obj_2_by_key = TestModel('2') # try to update item without getting it first + obj_2_by_key.update( + actions=[ + TestModel.scores.set(2), + TestModel.version.set(TestModel.version + 1) # increment version manually + ], + add_version_condition=False + ) + updated_obj_2 = TestModel.get('2') + assert updated_obj_2.scores == 2 + assert updated_obj_2.version == 2 + + TestModel.delete_table() From a87409d8e6ec6fadee658ce08317ebc07602b2b6 Mon Sep 17 00:00:00 2001 From: bpsoos Date: Wed, 24 Jul 2024 15:10:12 +0200 Subject: [PATCH 3/4] fixes tests --- dynamodb-local-metadata.json | 1 + tests/integration/model_integration_test.py | 17 ++++++++--------- .../integration/test_transaction_integration.py | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 dynamodb-local-metadata.json diff --git a/dynamodb-local-metadata.json b/dynamodb-local-metadata.json new file mode 100644 index 00000000..19d7e137 --- /dev/null +++ b/dynamodb-local-metadata.json @@ -0,0 +1 @@ +{"installationId":"a7dc8936-edc1-48ab-8470-903f44047a15","telemetryEnabled":"true"} \ No newline at end of file diff --git a/tests/integration/model_integration_test.py b/tests/integration/model_integration_test.py index c77af5ca..f4e962f2 100644 --- a/tests/integration/model_integration_test.py +++ b/tests/integration/model_integration_test.py @@ -155,7 +155,7 @@ class Meta: table_name = 'pynamodb-ci' host = ddb_url forum = UnicodeAttribute(hash_key=True) - scores = NumberSetAttribute() + score = NumberAttribute(null=True) version = VersionAttribute() if TestModel.exists(): @@ -165,39 +165,38 @@ class Meta: obj = TestModel('1') obj.save() assert TestModel.get('1').version == 1 - obj.scores = 1 + obj.score = 1 obj.save() assert TestModel.get('1').version == 2 obj_by_key = TestModel('1') # try to update item without getting it first obj_by_key.update( actions=[ - TestModel.scores.set(2), # no version increment + TestModel.score.set(2), # no version increment ], add_version_condition=False ) updated_obj = TestModel.get('1') - assert updated_obj.scores == 2 + assert updated_obj.score == 2 assert updated_obj.version == 2 - obj_2 = TestModel('2') obj_2.save() assert TestModel.get('2').version == 1 - obj_2.scores = 1 + obj_2.score = 1 obj_2.save() assert TestModel.get('2').version == 2 obj_2_by_key = TestModel('2') # try to update item without getting it first obj_2_by_key.update( actions=[ - TestModel.scores.set(2), + TestModel.score.set(2), TestModel.version.set(TestModel.version + 1) # increment version manually ], add_version_condition=False ) updated_obj_2 = TestModel.get('2') - assert updated_obj_2.scores == 2 - assert updated_obj_2.version == 2 + assert updated_obj_2.score == 2 + assert updated_obj_2.version == 3 TestModel.delete_table() diff --git a/tests/integration/test_transaction_integration.py b/tests/integration/test_transaction_integration.py index 48512d61..1ab31301 100644 --- a/tests/integration/test_transaction_integration.py +++ b/tests/integration/test_transaction_integration.py @@ -474,5 +474,5 @@ def test_transaction_write_increment_version_without_version_attribute_condition ) foo_updated = Foo.get(23) - assert foo_updated.version == 2 assert foo_updated.star == 'birdistheword' + assert foo_updated.version == 3 From b0aa8bf4a92fabaef37404a7e1c4d5e98509adc1 Mon Sep 17 00:00:00 2001 From: bpsoos Date: Wed, 24 Jul 2024 16:03:28 +0200 Subject: [PATCH 4/4] removes ddb local metadata --- dynamodb-local-metadata.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 dynamodb-local-metadata.json diff --git a/dynamodb-local-metadata.json b/dynamodb-local-metadata.json deleted file mode 100644 index 19d7e137..00000000 --- a/dynamodb-local-metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"installationId":"a7dc8936-edc1-48ab-8470-903f44047a15","telemetryEnabled":"true"} \ No newline at end of file