BREAKING Inner
Schema
classes that use inheritance must use bases that explicitly extend from the base class of the serialization package.Previously this was allowed:
from schematics.types import StringType class Mixin: foo = StringType(required=True) class MyModel(DynaModel): class Table: name = "table" hash_key = "foo" read = 1 write = 1 class Schema(Mixin): bar = StringType()
DynamORM would implicitly add the base Schematics model to the MRO of the Schema. However, this caused problems when you want to use an explicitly declared model as the base mixin since our serialization packages already apply metaclass logic to the fields.
Now, you must always explicitly inherit from the base class:
from schematics.models import Model from schematics.types import StringType class Mixin(Model): foo = String(required=True) class MyModel(DynaModel): class Table: name = "table" hash_key = "foo" read = 1 write = 1 class Schema(Mixin): bar = String()
- The internal
DynamORMSchema.base_field_type()
function was unused and has been removed
Enable support for updating nested paths in
Table.update
. Like functions (likeminus
orif_not_exists
) nested paths are also separated using the double-underscore syntax. For example, given an attributefoo
of an itemi
::"foo": { "bar": { "a": 1 }, "baz": 10 } i.update(foo__bar__a=42) "foo": { "bar": { "a": 42 }, "baz": 10 } i.update(foo__baz__plus=32) "foo": { "bar": { "a": 42 }, "baz": 42 }
This works because DynamoDB allows updating of nested attributes, using something like JSON path. From the DynamoDB Developer Guide:
aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"789"}}' \ --update-expression "SET #pr.#5star[1] = :r5, #pr.#3star = :r3" \ --expression-attribute-names '{ "#pr": "ProductReviews", "#5star": "FiveStar", "#3star": "ThreeStar" }' \ --expression-attribute-values '{ ":r5": { "S": "Very happy with my purchase" }, ":r3": { "L": [ { "S": "Just OK - not that great" } ] } }' \ --return-values ALL_NEW
Note that the attribute names along the nested path are broken up - this helps distinguish a nested update from a flat key like
my.flat.key
that contains a period.
- Address
DeprecationWarning
forcollections.abc
in Python 3.3+
- Ensure that
dynamorm_validate
actually callsschematics
validation.
- Check that recursive mode is enabled before warning about trying to use both limit and recursive.
- Ensure GitHub pages serves our static documentation content
- No functional library changes
Bug fix: Don't mutate dictionaries passed to table methods.
This caused problems with
ReadIterator
objects that called.again()
because the underlying Table object would end up mutating state on the iterator object.
- Bug fix: Ensure keys are normalized when calling
.delete()
on a model.
- Performance: Avoid validating twice when calling
.save()
on a model.
- Fix documentation deployment (broken since 0.9.6)
- Use Black (https://github.com/psf/black) for formatting code
- No functional library changes
- Switch to
tox
for running tests - Documentation improvements
- No functional library changes
- Add support for Marshmallow version 3
- Bump minimum schematics version to 2.10
- Ignore schematics warnings during test
- Add extras_require to setup.py to specify minimum versions of schematics & marshmallow
- Documentation update
BACKWARDS INCOMPATIBLE CHANGE!
Model.query
andModel.scan
no longer return ALL available items. Instead they stop at each 1Mb page. You can keep the existing behavior by adding a.recursive()
call to the return value.Before:
books = Books.scan()
After:
books = Books.scan().recursive()
This version introduces the
ReadIterator
object which is returned from query and scan operations. This object exposes functions that allow for better control over how a query/scan is executed. See the usage docs for full details.