Announcement here and PutItem reference here
Empty String and Binary attribute values are allowed. Attribute values of type String and Binary must have a length greater than zero if the attribute is used as a key attribute for a table or index.
This may be a breaking change if "" changes from meaning "no value please ensure deletion during update" to "put an empty value". From Type._dump and String.dynamo_dump it appears that "" gets transformed to None before _dump and then returns actions.wrap(None) (implemented here) which returns NONE_SENTINEL (defined here as a remove action).
There's a question about where key vs non-key constraints are handled. Since load/dump take a context object we could push is_key=True into the context and let the load/dump function sort out validity, or keep it simple and let the caller inspect the returned value and throw exceptions.
Finally, there's probably some complexity around DynamicType and StringSet/BinarySet that need to be figured out.
Some links to provide context around current design decisions and where changes are anticipated:
Announcement here and PutItem reference here
This may be a breaking change if
""changes from meaning "no value please ensure deletion during update" to "put an empty value". FromType._dumpandString.dynamo_dumpit appears that""gets transformed toNonebefore_dumpand then returnsactions.wrap(None)(implemented here) which returnsNONE_SENTINEL(defined here as a remove action).There's a question about where key vs non-key constraints are handled. Since load/dump take a context object we could push
is_key=Trueinto the context and let the load/dump function sort out validity, or keep it simple and let the caller inspect the returned value and throw exceptions.Finally, there's probably some complexity around
DynamicTypeandStringSet/BinarySetthat need to be figured out.Some links to provide context around current design decisions and where changes are anticipated:
NoneType._dump,Type._loadString.dynamo_dump,String.dynamo_loaddynamo_load,dynamo_dumpmethods for string/binary types that handle None/empty)DynamicType(can't guess ifNonemeans empty Binary or empty String, continue to throw?)DynamicType.backing_type_fordoes this assumption still hold, or will an empty set need to throw since it's ambiguous? What aboutset(None)?