Hello community,
here is the log from the commit of package python-pynamodb for openSUSE:Factory
checked in at 2020-07-20 21:05:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pynamodb (Old)
and /work/SRC/openSUSE:Factory/.python-pynamodb.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pynamodb"
Mon Jul 20 21:05:15 2020 rev:3 rq:821878 version:4.3.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pynamodb/python-pynamodb.changes
2020-03-09 18:34:12.490020909 +0100
+++
/work/SRC/openSUSE:Factory/.python-pynamodb.new.3592/python-pynamodb.changes
2020-07-20 21:06:52.253427475 +0200
@@ -1,0 +2,10 @@
+Fri Jul 3 15:17:46 UTC 2020 - Marketa Calabkova <[email protected]>
+
+- Update to 4.3.2
+ * Fix discrepancy between runtime and type-checker's perspective of Index
and derived types
+ * Add ListAttribute.remove_indexes action for removing specific indexes from
a ListAttribute
+ * Type stub fixes
+ * Prevent integration tests from being packaged
+ * Various documentation fixes
+
+-------------------------------------------------------------------
Old:
----
pynamodb-4.3.1.tar.gz
New:
----
pynamodb-4.3.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pynamodb.spec ++++++
--- /var/tmp/diff_new_pack.L95Shg/_old 2020-07-20 21:06:54.313429564 +0200
+++ /var/tmp/diff_new_pack.L95Shg/_new 2020-07-20 21:06:54.317429568 +0200
@@ -18,7 +18,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-pynamodb
-Version: 4.3.1
+Version: 4.3.2
Release: 0
Summary: Python Interface to DynamoDB
License: MIT
@@ -28,14 +28,14 @@
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
-Requires: python-botocore >= 1.2.54
+Requires: python-botocore >= 1.12.54
Requires: python-python-dateutil >= 2.1
Requires: python-six
Recommends: python-blinker >= 1.3
BuildArch: noarch
# SECTION test requirements
BuildRequires: %{python_module blinker >= 1.3}
-BuildRequires: %{python_module botocore >= 1.2.54}
+BuildRequires: %{python_module botocore >= 1.12.54}
BuildRequires: %{python_module pytest-mock}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module python-dateutil >= 2.1}
++++++ pynamodb-4.3.1.tar.gz -> pynamodb-4.3.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/PKG-INFO new/pynamodb-4.3.2/PKG-INFO
--- old/pynamodb-4.3.1/PKG-INFO 2020-01-25 04:33:50.000000000 +0100
+++ new/pynamodb-4.3.2/PKG-INFO 2020-04-28 16:17:22.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pynamodb
-Version: 4.3.1
+Version: 4.3.2
Summary: A Pythonic Interface to DynamoDB
Home-page: http://jlafon.io/pynamodb.html
Author: Jharrod LaFon
@@ -28,7 +28,7 @@
Useful links:
* See the full documentation at https://pynamodb.readthedocs.io/
- * Ask questions at `Google group
<https://groups.google.com/forum/#!forum/pynamodb>`_
+ * Ask questions in the `GitHub issues
<https://github.com/pynamodb/PynamoDB/issues>`_
* See release notes at
https://pynamodb.readthedocs.io/en/latest/release_notes.html
Installation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/README.rst
new/pynamodb-4.3.2/README.rst
--- old/pynamodb-4.3.1/README.rst 2020-01-25 04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/README.rst 2020-04-28 16:16:17.000000000 +0200
@@ -20,7 +20,7 @@
Useful links:
* See the full documentation at https://pynamodb.readthedocs.io/
-* Ask questions at `Google group
<https://groups.google.com/forum/#!forum/pynamodb>`_
+* Ask questions in the `GitHub issues
<https://github.com/pynamodb/PynamoDB/issues>`_
* See release notes at
https://pynamodb.readthedocs.io/en/latest/release_notes.html
Installation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/__init__.py
new/pynamodb-4.3.2/pynamodb/__init__.py
--- old/pynamodb-4.3.1/pynamodb/__init__.py 2020-01-25 04:33:12.000000000
+0100
+++ new/pynamodb-4.3.2/pynamodb/__init__.py 2020-04-28 16:16:17.000000000
+0200
@@ -7,4 +7,4 @@
"""
__author__ = 'Jharrod LaFon'
__license__ = 'MIT'
-__version__ = '4.3.1'
+__version__ = '4.3.2'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/_compat.py
new/pynamodb-4.3.2/pynamodb/_compat.py
--- old/pynamodb-4.3.1/pynamodb/_compat.py 2020-01-25 04:33:12.000000000
+0100
+++ new/pynamodb-4.3.2/pynamodb/_compat.py 2020-04-28 16:16:17.000000000
+0200
@@ -6,13 +6,28 @@
else:
from inspect import getfullargspec
+
+class FakeGenericMeta(type):
+ """Poor man's Generic[T] that doesn't depend on typing. The real generics
are in the type stubs."""
+ def __getitem__(self, item):
+ return self
+
+
def load_module(name, path):
"""Load module using the Python version compatible function."""
if sys.version_info >= (3, 3):
from importlib.machinery import SourceFileLoader
- return SourceFileLoader(name, path).load_module()
- else:
+
+ # Typeshed is incorrect in requiring a string arg to `load_module`,
+ # as this works with no args or a None arg.
+ # Even `load_module` is now deprecated, so we should update to just
+ # using the following approach in >= python 3.5:
+ #
https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly
+ loader = SourceFileLoader(name, path)
+ return loader.load_module() # type: ignore
+ else:
from imp import load_source
return load_source(name, path)
-__all__ = ('getfullargspec', 'load_module')
+
+__all__ = ('getfullargspec', 'FakeGenericMeta', 'load_module')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/attributes.py
new/pynamodb-4.3.2/pynamodb/attributes.py
--- old/pynamodb-4.3.1/pynamodb/attributes.py 2020-01-25 04:33:12.000000000
+0100
+++ new/pynamodb-4.3.2/pynamodb/attributes.py 2020-04-28 16:16:17.000000000
+0200
@@ -961,6 +961,11 @@
raise ValueError("'of' must be subclass of MapAttribute")
self.element_type = of
+ def remove_indexes(self, *indexes):
+ if not all([isinstance(i, int) for i in indexes]):
+ raise ValueError("Method 'remove_indexes' arguments must be 'int'")
+ return Path(self).remove_list_elements(*indexes)
+
def serialize(self, values):
"""
Encode the given list of objects into a list of AttributeValue types.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/attributes.pyi
new/pynamodb-4.3.2/pynamodb/attributes.pyi
--- old/pynamodb-4.3.1/pynamodb/attributes.pyi 2020-01-25 04:33:12.000000000
+0100
+++ new/pynamodb-4.3.2/pynamodb/attributes.pyi 2020-04-28 16:16:17.000000000
+0200
@@ -9,7 +9,7 @@
_Decrement, _IfNotExists, _Increment, _ListAppend
)
from pynamodb.expressions.update import (
- AddAction, DeleteAction, RemoveAction, SetAction
+ AddAction, DeleteAction, RemoveAction, SetAction, ListRemoveAction
)
@@ -168,6 +168,8 @@
def __get__(self: _A, instance: None, owner: Any) -> _A: ...
@overload
def __get__(self, instance: Any, owner: Any) -> List[_T]: ...
+ def remove_indexes(self, *indexes: int) -> Union[ListRemoveAction]: ...
+
DESERIALIZE_CLASS_MAP: Dict[Text, Attribute]
SERIALIZE_CLASS_MAP: Dict[Type, Attribute]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/expressions/operand.py
new/pynamodb-4.3.2/pynamodb/expressions/operand.py
--- old/pynamodb-4.3.1/pynamodb/expressions/operand.py 2020-01-25
04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/pynamodb/expressions/operand.py 2020-04-28
16:16:17.000000000 +0200
@@ -6,7 +6,7 @@
BeginsWith, Between, Comparison, Contains, Exists, In, IsType, NotExists
)
from pynamodb.expressions.update import (
- AddAction, DeleteAction, RemoveAction, SetAction
+ AddAction, DeleteAction, RemoveAction, SetAction, ListRemoveAction
)
from pynamodb.expressions.util import get_path_segments,
get_value_placeholder, substitute_names
from six import string_types
@@ -277,6 +277,9 @@
# Returns an update action that removes this attribute from the item
return RemoveAction(self)
+ def remove_list_elements(self, *indexes):
+ return ListRemoveAction(self, *indexes)
+
def add(self, *values):
# Returns an update action that appends the given values to a set or
mathematically adds a value to a number
value = values[0] if len(values) == 1 else values
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/expressions/operand.pyi
new/pynamodb-4.3.2/pynamodb/expressions/operand.pyi
--- old/pynamodb-4.3.1/pynamodb/expressions/operand.pyi 2020-01-25
04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/pynamodb/expressions/operand.pyi 2020-04-28
16:16:17.000000000 +0200
@@ -5,7 +5,7 @@
BeginsWith, Between, Comparison, Contains, Exists, In, IsType, NotExists
)
from pynamodb.expressions.update import (
- AddAction, DeleteAction, RemoveAction, SetAction
+ AddAction, DeleteAction, RemoveAction, SetAction, ListRemoveAction
)
@@ -78,3 +78,4 @@
def contains(self, item: Any) -> Contains: ...
def set(self, value: Any) -> SetAction: ...
def remove(self) -> RemoveAction: ...
+ def remove_list_elements(self, *indexes: int) -> ListRemoveAction: ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/expressions/update.py
new/pynamodb-4.3.2/pynamodb/expressions/update.py
--- old/pynamodb-4.3.1/pynamodb/expressions/update.py 2020-01-25
04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/pynamodb/expressions/update.py 2020-04-28
16:16:17.000000000 +0200
@@ -36,6 +36,17 @@
super(RemoveAction, self).__init__(path)
+class ListRemoveAction(Action):
+ """
+ The List REMOVE action deletes an element from a list item based on the
index.
+ """
+ format_string = None
+
+ def __init__(self, path, *indexes):
+ self.format_string = ", ".join("{{0}}[{}]".format(index) for index in
indexes)
+ super(ListRemoveAction, self).__init__(path)
+
+
class AddAction(Action):
"""
The ADD action appends elements to a set or mathematically adds to a
number attribute.
@@ -65,6 +76,7 @@
self.remove_actions = []
self.add_actions = []
self.delete_actions = []
+ self.list_remove_actions = []
for action in actions:
self.add_action(action)
@@ -73,6 +85,8 @@
self.set_actions.append(action)
elif isinstance(action, RemoveAction):
self.remove_actions.append(action)
+ elif isinstance(action, ListRemoveAction):
+ self.list_remove_actions.append(action)
elif isinstance(action, AddAction):
self.add_actions.append(action)
elif isinstance(action, DeleteAction):
@@ -84,6 +98,7 @@
expression = None
expression = self._add_clause(expression, 'SET', self.set_actions,
placeholder_names, expression_attribute_values)
expression = self._add_clause(expression, 'REMOVE',
self.remove_actions, placeholder_names, expression_attribute_values)
+ expression = self._add_clause(expression, 'REMOVE',
self.list_remove_actions, placeholder_names, expression_attribute_values)
expression = self._add_clause(expression, 'ADD', self.add_actions,
placeholder_names, expression_attribute_values)
expression = self._add_clause(expression, 'DELETE',
self.delete_actions, placeholder_names, expression_attribute_values)
return expression
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/expressions/update.pyi
new/pynamodb-4.3.2/pynamodb/expressions/update.pyi
--- old/pynamodb-4.3.1/pynamodb/expressions/update.pyi 2020-01-25
04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/pynamodb/expressions/update.pyi 2020-04-28
16:16:17.000000000 +0200
@@ -15,6 +15,10 @@
def __init__(self, path: Path) -> None: ...
+class ListRemoveAction(Action):
+ def __init__(self, path: Path, *indexes: int) -> None: ...
+
+
class AddAction(Action):
def __init__(self, path: Path, subset: Path) -> None: ...
@@ -26,6 +30,7 @@
class Update(object):
set_actions: List[SetAction]
remove_actions: List[RemoveAction]
+ list_remove_actions: List[ListRemoveAction]
add_actions: List[AddAction]
delete_actions: List[DeleteAction]
def __init__(self, *actions: Action) -> None: ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/indexes.py
new/pynamodb-4.3.2/pynamodb/indexes.py
--- old/pynamodb-4.3.1/pynamodb/indexes.py 2020-01-25 04:33:12.000000000
+0100
+++ new/pynamodb-4.3.2/pynamodb/indexes.py 2020-04-28 16:16:17.000000000
+0200
@@ -3,6 +3,7 @@
"""
from inspect import getmembers
+from pynamodb._compat import FakeGenericMeta
from pynamodb.constants import (
INCLUDE, ALL, KEYS_ONLY, ATTR_NAME, ATTR_TYPE, KEY_TYPE, ATTR_TYPE_MAP,
KEY_SCHEMA,
ATTR_DEFINITIONS, META_CLASS_NAME
@@ -13,7 +14,7 @@
from six import with_metaclass
-class IndexMeta(type):
+class IndexMeta(FakeGenericMeta):
"""
Index meta class
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/models.py
new/pynamodb-4.3.2/pynamodb/models.py
--- old/pynamodb-4.3.1/pynamodb/models.py 2020-01-25 04:33:12.000000000
+0100
+++ new/pynamodb-4.3.2/pynamodb/models.py 2020-04-28 16:16:17.000000000
+0200
@@ -356,6 +356,8 @@
def delete(self, condition=None):
"""
Deletes this object from dynamodb
+
+ :raises pynamodb.exceptions.DeleteError: If the record can not be
deleted
"""
args, kwargs = self._get_save_args(attributes=False, null_check=False)
version_condition = self._handle_version_attribute(kwargs)
@@ -371,6 +373,8 @@
:param actions: a list of Action updates to apply
:param condition: an optional Condition on which to update
+ :raises ModelInstance.DoesNotExist: if the object to be updated does
not exist
+ :raises pynamodb.exceptions.UpdateError: if the `condition` is not met
"""
if not isinstance(actions, list) or len(actions) == 0:
raise TypeError("the value of `actions` is expected to be a
non-empty list")
@@ -411,6 +415,7 @@
Retrieves this object's data from dynamodb and syncs this local object
:param consistent_read: If True, then a consistent read is performed.
+ :raises ModelInstance.DoesNotExist: if the object to be updated does
not exist
"""
args, kwargs = self._get_save_args(attributes=False)
kwargs.setdefault('consistent_read', consistent_read)
@@ -471,8 +476,9 @@
:param hash_key: The hash key of the desired item
:param range_key: The range key of the desired item, only used when
appropriate.
- :param consistent_read
- :param attributes_to_get
+ :param consistent_read:
+ :param attributes_to_get:
+ :raises ModelInstance.DoesNotExist: if the object to be updated does
not exist
"""
hash_key, range_key = cls._serialize_keys(hash_key, range_key)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb/models.pyi
new/pynamodb-4.3.2/pynamodb/models.pyi
--- old/pynamodb-4.3.1/pynamodb/models.pyi 2020-01-25 04:33:12.000000000
+0100
+++ new/pynamodb-4.3.2/pynamodb/models.pyi 2020-04-28 16:16:17.000000000
+0200
@@ -21,7 +21,7 @@
def __init__(self, name: Text, bases: Tuple[type, ...], attrs: Dict[Any,
Any]) -> None: ...
_T = TypeVar('_T', bound='Model')
-KeyType = Union[Text, bytes, float, int, Tuple]
+KeyType = Any
class Model(metaclass=MetaModel):
DoesNotExist = DoesNotExist
@@ -82,6 +82,8 @@
limit: Optional[int] = ...,
last_evaluated_key: Optional[Dict[str, Dict[str, Any]]] = ...,
page_size: Optional[int] = ...,
+ consistent_read: bool = ...,
+ index_name: Optional[Text] = ...,
rate_limit: Optional[float] = ...,
attributes_to_get: Optional[List[str]] = ...,
) -> ResultIterator[_T]: ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb.egg-info/PKG-INFO
new/pynamodb-4.3.2/pynamodb.egg-info/PKG-INFO
--- old/pynamodb-4.3.1/pynamodb.egg-info/PKG-INFO 2020-01-25
04:33:50.000000000 +0100
+++ new/pynamodb-4.3.2/pynamodb.egg-info/PKG-INFO 2020-04-28
16:17:22.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pynamodb
-Version: 4.3.1
+Version: 4.3.2
Summary: A Pythonic Interface to DynamoDB
Home-page: http://jlafon.io/pynamodb.html
Author: Jharrod LaFon
@@ -28,7 +28,7 @@
Useful links:
* See the full documentation at https://pynamodb.readthedocs.io/
- * Ask questions at `Google group
<https://groups.google.com/forum/#!forum/pynamodb>`_
+ * Ask questions in the `GitHub issues
<https://github.com/pynamodb/PynamoDB/issues>`_
* See release notes at
https://pynamodb.readthedocs.io/en/latest/release_notes.html
Installation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb.egg-info/SOURCES.txt
new/pynamodb-4.3.2/pynamodb.egg-info/SOURCES.txt
--- old/pynamodb-4.3.1/pynamodb.egg-info/SOURCES.txt 2020-01-25
04:33:50.000000000 +0100
+++ new/pynamodb-4.3.2/pynamodb.egg-info/SOURCES.txt 2020-04-28
16:17:22.000000000 +0200
@@ -47,11 +47,4 @@
pynamodb/expressions/update.py
pynamodb/expressions/update.pyi
pynamodb/expressions/util.py
-pynamodb/expressions/util.pyi
-tests/integration/__init__.py
-tests/integration/base_integration_test.py
-tests/integration/binary_update_test.py
-tests/integration/conftest.py
-tests/integration/model_integration_test.py
-tests/integration/table_integration_test.py
-tests/integration/test_transaction_integration.py
\ No newline at end of file
+pynamodb/expressions/util.pyi
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/pynamodb.egg-info/top_level.txt
new/pynamodb-4.3.2/pynamodb.egg-info/top_level.txt
--- old/pynamodb-4.3.1/pynamodb.egg-info/top_level.txt 2020-01-25
04:33:50.000000000 +0100
+++ new/pynamodb-4.3.2/pynamodb.egg-info/top_level.txt 2020-04-28
16:17:22.000000000 +0200
@@ -1,2 +1 @@
pynamodb
-tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/requirements-dev.txt
new/pynamodb-4.3.2/requirements-dev.txt
--- old/pynamodb-4.3.1/requirements-dev.txt 2020-01-25 04:33:12.000000000
+0100
+++ new/pynamodb-4.3.2/requirements-dev.txt 2020-04-28 16:16:17.000000000
+0200
@@ -9,3 +9,5 @@
coveralls
mypy==0.761;python_version>="3.7"
pytest-cov
+sphinx
+sphinx-rtd-theme
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/setup.py new/pynamodb-4.3.2/setup.py
--- old/pynamodb-4.3.1/setup.py 2020-01-25 04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/setup.py 2020-04-28 16:16:17.000000000 +0200
@@ -31,7 +31,7 @@
setup(
name='pynamodb',
version=__import__('pynamodb').__version__,
- packages=find_packages(exclude=('tests',)),
+ packages=find_packages(exclude=('tests', 'tests.integration',)),
url='http://jlafon.io/pynamodb.html',
author='Jharrod LaFon',
author_email='[email protected]',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pynamodb-4.3.1/tests/integration/base_integration_test.py
new/pynamodb-4.3.2/tests/integration/base_integration_test.py
--- old/pynamodb-4.3.1/tests/integration/base_integration_test.py
2020-01-25 04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/tests/integration/base_integration_test.py
1970-01-01 01:00:00.000000000 +0100
@@ -1,169 +0,0 @@
-"""
-Runs tests against dynamodb
-"""
-import time
-
-from pynamodb.connection import Connection
-from pynamodb.constants import PROVISIONED_THROUGHPUT, READ_CAPACITY_UNITS
-from pynamodb.expressions.condition import BeginsWith, NotExists
-from pynamodb.expressions.operand import Path, Value
-from pynamodb.exceptions import TableDoesNotExist
-from pynamodb.types import STRING, HASH, RANGE, NUMBER
-
-import pytest
-
-
[email protected]
-def test_connection_integration(ddb_url):
- table_name = 'pynamodb-ci-connection'
-
- # For use with a fake dynamodb connection
- # See: http://aws.amazon.com/dynamodb/developer-resources/
- conn = Connection(host=ddb_url)
-
- print(conn)
- print("conn.describe_table...")
- table = None
- try:
- table = conn.describe_table(table_name)
- except TableDoesNotExist:
- params = {
- 'read_capacity_units': 1,
- 'write_capacity_units': 1,
- 'attribute_definitions': [
- {
- 'attribute_type': STRING,
- 'attribute_name': 'Forum'
- },
- {
- 'attribute_type': STRING,
- 'attribute_name': 'Thread'
- },
- {
- 'attribute_type': STRING,
- 'attribute_name': 'AltKey'
- },
- {
- 'attribute_type': NUMBER,
- 'attribute_name': 'number'
- }
- ],
- 'key_schema': [
- {
- 'key_type': HASH,
- 'attribute_name': 'Forum'
- },
- {
- 'key_type': RANGE,
- 'attribute_name': 'Thread'
- }
- ],
- 'global_secondary_indexes': [
- {
- 'index_name': 'alt-index',
- 'key_schema': [
- {
- 'KeyType': 'HASH',
- 'AttributeName': 'AltKey'
- }
- ],
- 'projection': {
- 'ProjectionType': 'KEYS_ONLY'
- },
- 'provisioned_throughput': {
- 'ReadCapacityUnits': 1,
- 'WriteCapacityUnits': 1,
- }
- }
- ],
- 'local_secondary_indexes': [
- {
- 'index_name': 'view-index',
- 'key_schema': [
- {
- 'KeyType': 'HASH',
- 'AttributeName': 'Forum'
- },
- {
- 'KeyType': 'RANGE',
- 'AttributeName': 'AltKey'
- }
- ],
- 'projection': {
- 'ProjectionType': 'KEYS_ONLY'
- }
- }
- ]
- }
- print("conn.create_table...")
- conn.create_table(table_name, **params)
-
- while table is None:
- time.sleep(1)
- table = conn.describe_table(table_name)
-
- while table['TableStatus'] == 'CREATING':
- time.sleep(2)
- table = conn.describe_table(table_name)
- print("conn.list_tables")
- conn.list_tables()
- print("conn.update_table...")
-
- conn.update_table(
- table_name,
-
read_capacity_units=table.get(PROVISIONED_THROUGHPUT).get(READ_CAPACITY_UNITS)
+ 1,
- write_capacity_units=2
- )
-
- table = conn.describe_table(table_name)
-
- while table['TableStatus'] != 'ACTIVE':
- time.sleep(2)
- table = conn.describe_table(table_name)
-
- print("conn.put_item")
- conn.put_item(
- table_name,
- 'item1-hash',
- range_key='item1-range',
- attributes={'foo': {'S': 'bar'}},
- condition=NotExists(Path('Forum')),
- )
- conn.get_item(
- table_name,
- 'item1-hash',
- range_key='item1-range'
- )
- conn.delete_item(
- table_name,
- 'item1-hash',
- range_key='item1-range'
- )
-
- items = []
- for i in range(10):
- items.append(
- {"Forum": "FooForum", "Thread": "thread-{}".format(i)}
- )
- print("conn.batch_write_items...")
- conn.batch_write_item(
- table_name,
- put_items=items
- )
- print("conn.batch_get_items...")
- data = conn.batch_get_item(
- table_name,
- items
- )
- print("conn.query...")
- conn.query(
- table_name,
- "FooForum",
- range_key_condition=(BeginsWith(Path('Thread'), Value('thread'))),
- )
- print("conn.scan...")
- conn.scan(
- table_name,
- )
- print("conn.delete_table...")
- conn.delete_table(table_name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pynamodb-4.3.1/tests/integration/binary_update_test.py
new/pynamodb-4.3.2/tests/integration/binary_update_test.py
--- old/pynamodb-4.3.1/tests/integration/binary_update_test.py 2020-01-25
04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/tests/integration/binary_update_test.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,45 +0,0 @@
-import pytest
-
-from pynamodb.attributes import UnicodeAttribute, BinaryAttribute,
BinarySetAttribute
-from pynamodb.models import Model
-
-
[email protected]
-def test_binary_attribute_update(ddb_url):
- class DataModel(Model):
- class Meta:
- table_name = 'binary_attr_update'
- host = ddb_url
- pkey = UnicodeAttribute(hash_key=True)
- data = BinaryAttribute()
-
- DataModel.create_table(read_capacity_units=1, write_capacity_units=1,
wait=True)
- data = b'\x00hey\xfb'
- pkey = 'pkey'
- DataModel(pkey, data=data).save()
- m = DataModel.get(pkey)
- assert m.data == data
-
- new_data = b'\xff'
- m.update(actions=[DataModel.data.set(new_data)])
- assert new_data == m.data
-
[email protected]
-def test_binary_set_attribute_update(ddb_url):
- class DataModel(Model):
- class Meta:
- table_name = 'binary_set_attr_update'
- host = ddb_url
- pkey = UnicodeAttribute(hash_key=True)
- data = BinarySetAttribute()
-
- DataModel.create_table(read_capacity_units=1, write_capacity_units=1,
wait=True)
- data = {b'\x00hey\xfb', b'\x00beautiful\xfb'}
- pkey = 'pkey'
- DataModel(pkey, data=data).save()
- m = DataModel.get(pkey)
- assert m.data == data
-
- new_data = {b'\xff'}
- m.update(actions=[DataModel.data.set(new_data)])
- assert new_data == m.data
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pynamodb-4.3.1/tests/integration/conftest.py
new/pynamodb-4.3.2/tests/integration/conftest.py
--- old/pynamodb-4.3.1/tests/integration/conftest.py 2020-01-25
04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/tests/integration/conftest.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,19 +0,0 @@
-import os
-
-import pytest
-
-
[email protected](scope='module')
-def ddb_url():
- """Obtain the URL of a local DynamoDB instance.
-
- This is meant to be used with something like DynamoDB Local:
-
-
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html
-
- It must be set up "out of band"; we merely assume it exists on
- http://localhost:8000 or a URL specified though the
- PYNAMODB_INTEGRATION_TEST_DDB_URL environment variable.
- """
- ddb_url = os.getenv("PYNAMODB_INTEGRATION_TEST_DDB_URL")
- return "http://localhost:8000" if ddb_url is None else ddb_url
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pynamodb-4.3.1/tests/integration/model_integration_test.py
new/pynamodb-4.3.2/tests/integration/model_integration_test.py
--- old/pynamodb-4.3.1/tests/integration/model_integration_test.py
2020-01-25 04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/tests/integration/model_integration_test.py
1970-01-01 01:00:00.000000000 +0100
@@ -1,104 +0,0 @@
-"""
-Integration tests for the model API
-"""
-from datetime import datetime
-from pynamodb.models import Model
-from pynamodb.indexes import GlobalSecondaryIndex, AllProjection,
LocalSecondaryIndex
-from pynamodb.attributes import (
- UnicodeAttribute, BinaryAttribute, UTCDateTimeAttribute,
NumberSetAttribute, NumberAttribute,
- VersionAttribute)
-
-import pytest
-
-
-class LSIndex(LocalSecondaryIndex):
- """
- A model for the local secondary index
- """
- class Meta:
- projection = AllProjection()
- forum = UnicodeAttribute(hash_key=True)
- view = NumberAttribute(range_key=True)
-
-
-class GSIndex(GlobalSecondaryIndex):
- """
- A model for the secondary index
- """
- class Meta:
- projection = AllProjection()
- read_capacity_units = 2
- write_capacity_units = 1
- epoch = UTCDateTimeAttribute(hash_key=True)
-
-
[email protected]
-def test_model_integration(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)
- thread = UnicodeAttribute(range_key=True)
- view = NumberAttribute(default=0)
- view_index = LSIndex()
- epoch_index = GSIndex()
- epoch = UTCDateTimeAttribute(default=datetime.now)
- content = BinaryAttribute(null=True)
- scores = NumberSetAttribute()
- version = VersionAttribute()
-
- if not TestModel.exists():
- print("Creating table")
- TestModel.create_table(read_capacity_units=1, write_capacity_units=1,
wait=True)
-
- obj = TestModel('1', '2')
- obj.save()
- obj.refresh()
- obj = TestModel('foo', 'bar')
- obj.save()
- TestModel('foo2', 'bar2')
- obj3 = TestModel('setitem', 'setrange', scores={1, 2.1})
- obj3.save()
- obj3.refresh()
-
- with TestModel.batch_write() as batch:
- items = [TestModel('hash-{}'.format(x), '{}'.format(x)) for x in
range(10)]
- for item in items:
- batch.save(item)
-
- item_keys = [('hash-{}'.format(x), 'thread-{}'.format(x)) for x in
range(10)]
-
- for item in TestModel.batch_get(item_keys):
- print(item)
-
- for item in TestModel.query('setitem', TestModel.thread.startswith('set')):
- print("Query Item {}".format(item))
-
- with TestModel.batch_write() as batch:
- items = [TestModel('hash-{}'.format(x), '{}'.format(x)) for x in
range(10)]
- for item in items:
- print("Batch delete")
- batch.delete(item)
-
- for item in TestModel.scan():
- print("Scanned item: {}".format(item))
-
- tstamp = datetime.now()
- query_obj = TestModel('query_forum', 'query_thread')
- query_obj.forum = 'foo'
- query_obj.save()
- query_obj.update([TestModel.view.add(1)])
- for item in TestModel.epoch_index.query(tstamp):
- print("Item queried from index: {}".format(item))
-
- for item in TestModel.view_index.query('foo', TestModel.view > 0):
- print("Item queried from index: {}".format(item.view))
-
- print(query_obj.update([TestModel.view.add(1)],
condition=TestModel.forum.exists()))
- TestModel.delete_table()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pynamodb-4.3.1/tests/integration/table_integration_test.py
new/pynamodb-4.3.2/tests/integration/table_integration_test.py
--- old/pynamodb-4.3.1/tests/integration/table_integration_test.py
2020-01-25 04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/tests/integration/table_integration_test.py
1970-01-01 01:00:00.000000000 +0100
@@ -1,156 +0,0 @@
-"""
-Run tests against dynamodb using the table abstraction
-"""
-import time
-from pynamodb.constants import PROVISIONED_THROUGHPUT, READ_CAPACITY_UNITS
-from pynamodb.connection import TableConnection
-from pynamodb.expressions.condition import BeginsWith, NotExists
-from pynamodb.expressions.operand import Path, Value
-from pynamodb.exceptions import TableDoesNotExist
-from pynamodb.types import STRING, HASH, RANGE, NUMBER
-
-import pytest
-
-
[email protected]
-def test_table_integration(ddb_url):
- table_name = 'pynamodb-ci-table'
-
- # For use with a fake dynamodb connection
- # See: http://aws.amazon.com/dynamodb/developer-resources/
- conn = TableConnection(table_name, host=ddb_url)
- print(conn)
-
- print("conn.describe_table...")
- table = None
- try:
- table = conn.describe_table()
- except TableDoesNotExist:
- params = {
- 'read_capacity_units': 1,
- 'write_capacity_units': 1,
- 'attribute_definitions': [
- {
- 'attribute_type': STRING,
- 'attribute_name': 'Forum'
- },
- {
- 'attribute_type': STRING,
- 'attribute_name': 'Thread'
- },
- {
- 'attribute_type': STRING,
- 'attribute_name': 'AltKey'
- },
- {
- 'attribute_type': NUMBER,
- 'attribute_name': 'number'
- }
- ],
- 'key_schema': [
- {
- 'key_type': HASH,
- 'attribute_name': 'Forum'
- },
- {
- 'key_type': RANGE,
- 'attribute_name': 'Thread'
- }
- ],
- 'global_secondary_indexes': [
- {
- 'index_name': 'alt-index',
- 'key_schema': [
- {
- 'KeyType': 'HASH',
- 'AttributeName': 'AltKey'
- }
- ],
- 'projection': {
- 'ProjectionType': 'KEYS_ONLY'
- },
- 'provisioned_throughput': {
- 'ReadCapacityUnits': 1,
- 'WriteCapacityUnits': 1,
- }
- }
- ],
- 'local_secondary_indexes': [
- {
- 'index_name': 'view-index',
- 'key_schema': [
- {
- 'KeyType': 'HASH',
- 'AttributeName': 'Forum'
- },
- {
- 'KeyType': 'RANGE',
- 'AttributeName': 'AltKey'
- }
- ],
- 'projection': {
- 'ProjectionType': 'KEYS_ONLY'
- }
- }
- ]
- }
- print("conn.create_table...")
- conn.create_table(**params)
-
- while table is None:
- time.sleep(2)
- table = conn.describe_table()
- while table['TableStatus'] == 'CREATING':
- time.sleep(5)
- print(table['TableStatus'])
- table = conn.describe_table()
- print("conn.update_table...")
-
- conn.update_table(
-
read_capacity_units=table.get(PROVISIONED_THROUGHPUT).get(READ_CAPACITY_UNITS)
+ 1,
- write_capacity_units=2
- )
-
- table = conn.describe_table()
- while table['TableStatus'] != 'ACTIVE':
- time.sleep(2)
- table = conn.describe_table()
-
- print("conn.put_item")
- conn.put_item(
- 'item1-hash',
- range_key='item1-range',
- attributes={'foo': {'S': 'bar'}},
- condition=NotExists(Path('Forum')),
- )
- conn.get_item(
- 'item1-hash',
- range_key='item1-range'
- )
- conn.delete_item(
- 'item1-hash',
- range_key='item1-range'
- )
-
- items = []
- for i in range(10):
- items.append(
- {"Forum": "FooForum", "Thread": "thread-{}".format(i)}
- )
- print("conn.batch_write_items...")
- conn.batch_write_item(
- put_items=items
- )
- print("conn.batch_get_items...")
- data = conn.batch_get_item(
- items
- )
- print("conn.query...")
- conn.query(
- "FooForum",
- range_key_condition=(BeginsWith(Path('Thread'), Value('thread'))),
- )
- print("conn.scan...")
- conn.scan()
- print("conn.delete_table...")
- conn.delete_table()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pynamodb-4.3.1/tests/integration/test_transaction_integration.py
new/pynamodb-4.3.2/tests/integration/test_transaction_integration.py
--- old/pynamodb-4.3.1/tests/integration/test_transaction_integration.py
2020-01-25 04:33:12.000000000 +0100
+++ new/pynamodb-4.3.2/tests/integration/test_transaction_integration.py
1970-01-01 01:00:00.000000000 +0100
@@ -1,364 +0,0 @@
-import uuid
-from datetime import datetime
-
-import pytest
-
-from pynamodb.connection import Connection
-from pynamodb.exceptions import DoesNotExist, TransactWriteError,
TransactGetError, InvalidStateError
-
-
-from pynamodb.attributes import (
- NumberAttribute, UnicodeAttribute, UTCDateTimeAttribute, BooleanAttribute,
VersionAttribute
-)
-from pynamodb.transactions import TransactGet, TransactWrite
-
-from pynamodb.models import Model
-
-IDEMPOTENT_PARAMETER_MISMATCH = 'IdempotentParameterMismatchException'
-PROVISIONED_THROUGHPUT_EXCEEDED = 'ProvisionedThroughputExceededException'
-RESOURCE_NOT_FOUND = 'ResourceNotFoundException'
-TRANSACTION_CANCELLED = 'TransactionCanceledException'
-TRANSACTION_IN_PROGRESS = 'TransactionInProgressException'
-VALIDATION_EXCEPTION = 'ValidationException'
-
-
-class User(Model):
- class Meta:
- region = 'us-east-1'
- table_name = 'user'
-
- user_id = NumberAttribute(hash_key=True)
-
-
-class BankStatement(Model):
-
- class Meta:
- region = 'us-east-1'
- table_name = 'statement'
-
- user_id = NumberAttribute(hash_key=True)
- balance = NumberAttribute(default=0)
- active = BooleanAttribute(default=True)
-
-
-class LineItem(Model):
-
- class Meta:
- region = 'us-east-1'
- table_name = 'line-item'
-
- user_id = NumberAttribute(hash_key=True)
- created_at = UTCDateTimeAttribute(range_key=True, default=datetime.now())
- amount = NumberAttribute()
- currency = UnicodeAttribute()
-
-
-class DifferentRegion(Model):
-
- class Meta:
- region = 'us-east-2'
- table_name = 'different-region'
-
- entry_index = NumberAttribute(hash_key=True)
-
-
-class Foo(Model):
- class Meta:
- region = 'us-east-1'
- table_name = 'foo'
-
- bar = NumberAttribute(hash_key=True)
- star = UnicodeAttribute(null=True)
- version = VersionAttribute()
-
-
-TEST_MODELS = [
- BankStatement,
- DifferentRegion,
- LineItem,
- User,
- Foo
-]
-
-
[email protected](scope='module')
-def connection(ddb_url):
- yield Connection(host=ddb_url)
-
-
[email protected](scope='module', autouse=True)
-def create_tables(ddb_url):
- for m in TEST_MODELS:
- m.Meta.host = ddb_url
- m.create_table(
- read_capacity_units=10,
- write_capacity_units=10,
- wait=True
- )
-
- yield
-
- for m in TEST_MODELS:
- if m.exists():
- m.delete_table()
-
-
-def get_error_code(error):
- return error.cause.response['Error'].get('Code')
-
-
-def get_error_message(error):
- return error.cause.response['Error'].get('Message')
-
-
[email protected]
-def test_transact_write__error__idempotent_parameter_mismatch(connection):
- client_token = str(uuid.uuid4())
-
- with TransactWrite(connection=connection,
client_request_token=client_token) as transaction:
- transaction.save(User(1))
- transaction.save(User(2))
-
- with pytest.raises(TransactWriteError) as exc_info:
- # committing the first time, then adding more info and committing again
- with TransactWrite(connection=connection,
client_request_token=client_token) as transaction:
- transaction.save(User(3))
- assert get_error_code(exc_info.value) == IDEMPOTENT_PARAMETER_MISMATCH
-
- # ensure that the first request succeeded in creating new users
- assert User.get(1)
- assert User.get(2)
-
- with pytest.raises(DoesNotExist):
- # ensure it did not create the user from second request
- User.get(3)
-
-
[email protected]
-def test_transact_write__error__different_regions(connection):
- with pytest.raises(TransactWriteError) as exc_info:
- with TransactWrite(connection=connection) as transact_write:
- # creating a model in a table outside the region everyone else
operates in
- transact_write.save(DifferentRegion(entry_index=0))
- transact_write.save(BankStatement(1))
- transact_write.save(User(1))
- assert get_error_code(exc_info.value) == RESOURCE_NOT_FOUND
-
-
[email protected]
-def
test_transact_write__error__transaction_cancelled__condition_check_failure(connection):
- # create a users and a bank statements for them
- User(1).save()
- BankStatement(1).save()
-
- # attempt to do this as a transaction with the condition that they don't
already exist
- with pytest.raises(TransactWriteError) as exc_info:
- with TransactWrite(connection=connection) as transaction:
- transaction.save(User(1),
condition=(User.user_id.does_not_exist()))
- transaction.save(BankStatement(1),
condition=(BankStatement.user_id.does_not_exist()))
- assert get_error_code(exc_info.value) == TRANSACTION_CANCELLED
- assert 'ConditionalCheckFailed' in get_error_message(exc_info.value)
-
-
[email protected]
-def test_transact_write__error__multiple_operations_on_same_record(connection):
- BankStatement(1).save()
-
- # attempt to do a transaction with multiple operations on the same record
- with pytest.raises(TransactWriteError) as exc_info:
- with TransactWrite(connection=connection) as transaction:
- transaction.condition_check(BankStatement, 1,
condition=(BankStatement.user_id.exists()))
- transaction.update(BankStatement(1),
actions=[(BankStatement.balance.add(10))])
- assert get_error_code(exc_info.value) == VALIDATION_EXCEPTION
-
-
[email protected]
-def test_transact_get(connection):
- # making sure these entries exist, and with the expected info
- User(1).save()
- BankStatement(1).save()
- User(2).save()
- BankStatement(2, balance=100).save()
-
- # get users and statements we just created and assign them to variables
- with TransactGet(connection=connection) as transaction:
- _user1_future = transaction.get(User, 1)
- _statement1_future = transaction.get(BankStatement, 1)
- _user2_future = transaction.get(User, 2)
- _statement2_future = transaction.get(BankStatement, 2)
-
- user1 = _user1_future.get()
- statement1 = _statement1_future.get()
- user2 = _user2_future.get()
- statement2 = _statement2_future.get()
-
- assert user1.user_id == statement1.user_id == 1
- assert statement1.balance == 0
- assert user2.user_id == statement2.user_id == 2
- assert statement2.balance == 100
-
-
[email protected]
-def test_transact_get__does_not_exist(connection):
- with TransactGet(connection=connection) as transaction:
- _user_future = transaction.get(User, 100)
- with pytest.raises(User.DoesNotExist):
- _user_future.get()
-
-
[email protected]
-def test_transact_get__invalid_state(connection):
- with TransactGet(connection=connection) as transaction:
- _user_future = transaction.get(User, 100)
- with pytest.raises(InvalidStateError):
- _user_future.get()
-
-
[email protected]
-def test_transact_write(connection):
- # making sure these entries exist, and with the expected info
- BankStatement(1, balance=0).save()
- BankStatement(2, balance=100).save()
-
- # assert values are what we think they should be
- statement1 = BankStatement.get(1)
- statement2 = BankStatement.get(2)
- assert statement1.balance == 0
- assert statement2.balance == 100
-
- with TransactWrite(connection=connection) as transaction:
- # let the users send money to one another
- # create a credit line item to user 1's account
- transaction.save(
- LineItem(user_id=1, amount=50, currency='USD'),
- condition=(LineItem.user_id.does_not_exist()),
- )
- # create a debit to user 2's account
- transaction.save(
- LineItem(user_id=2, amount=-50, currency='USD'),
- condition=(LineItem.user_id.does_not_exist()),
- )
-
- # add credit to user 1's account
- transaction.update(statement1, actions=[BankStatement.balance.add(50)])
- # debit from user 2's account if they have enough in the bank
- transaction.update(
- statement2,
- actions=[BankStatement.balance.add(-50)],
- condition=(BankStatement.balance >= 50)
- )
-
- statement1.refresh()
- statement2.refresh()
- assert statement1.balance == statement2.balance == 50
-
-
[email protected]
-def test_transact_write__one_of_each(connection):
- User(1).save()
- User(2).save()
- statement = BankStatement(1, balance=100, active=True)
- statement.save()
-
- with TransactWrite(connection=connection) as transaction:
- transaction.condition_check(User, 1, condition=(User.user_id.exists()))
- transaction.delete(User(2))
- transaction.save(LineItem(4, amount=100, currency='USD'),
condition=(LineItem.user_id.does_not_exist()))
- transaction.update(
- statement,
- actions=[
- BankStatement.active.set(False),
- BankStatement.balance.set(0),
- ]
- )
-
- # confirming transaction correct and successful
- assert User.get(1)
- with pytest.raises(DoesNotExist):
- User.get(2)
-
- new_line_item = next(LineItem.query(4, scan_index_forward=False, limit=1),
None)
- assert new_line_item
- assert new_line_item.amount == 100
- assert new_line_item.currency == 'USD'
-
- statement.refresh()
- assert not statement.active
- assert statement.balance == 0
-
-
[email protected]
-def test_transaction_write_with_version_attribute(connection):
- foo1 = Foo(1)
- foo1.save()
- foo2 = Foo(2, star='bar')
- foo2.save()
- foo3 = Foo(3)
- foo3.save()
-
- with TransactWrite(connection=connection) as transaction:
- transaction.condition_check(Foo, 1, condition=(Foo.bar.exists()))
- transaction.delete(foo2)
- transaction.save(Foo(4))
- transaction.update(
- foo3,
- actions=[
- Foo.star.set('birdistheword'),
- ]
- )
-
- assert Foo.get(1).version == 1
- with pytest.raises(DoesNotExist):
- Foo.get(2)
- # Local object's version attribute is updated automatically.
- assert foo3.version == 2
- assert Foo.get(4).version == 1
-
-
[email protected]
-def test_transaction_get_with_version_attribute(connection):
- Foo(11).save()
- Foo(12, star='bar').save()
-
- with TransactGet(connection=connection) as transaction:
- foo1_future = transaction.get(Foo, 11)
- foo2_future = transaction.get(Foo, 12)
-
- foo1 = foo1_future.get()
- assert foo1.version == 1
- foo2 = foo2_future.get()
- assert foo2.version == 1
- assert foo2.star == 'bar'
-
-
[email protected]
-def
test_transaction_write_with_version_attribute_condition_failure(connection):
- foo = Foo(21)
- foo.save()
-
- foo2 = Foo(21)
-
- with pytest.raises(TransactWriteError) as exc_info:
- with TransactWrite(connection=connection) as transaction:
- transaction.save(Foo(21))
- assert get_error_code(exc_info.value) == TRANSACTION_CANCELLED
- assert 'ConditionalCheckFailed' in get_error_message(exc_info.value)
-
- with pytest.raises(TransactWriteError) as exc_info:
- with TransactWrite(connection=connection) as transaction:
- transaction.update(
- foo2,
- actions=[
- Foo.star.set('birdistheword'),
- ]
- )
- assert get_error_code(exc_info.value) == TRANSACTION_CANCELLED
- assert 'ConditionalCheckFailed' in get_error_message(exc_info.value)
- # Version attribute is not updated on failure.
- assert foo2.version is None
-
- with pytest.raises(TransactWriteError) as exc_info:
- with TransactWrite(connection=connection) as transaction:
- transaction.delete(foo2)
- assert get_error_code(exc_info.value) == TRANSACTION_CANCELLED
- assert 'ConditionalCheckFailed' in get_error_message(exc_info.value)