softprops / dynomite

⚡🦀 🧨 make your rust types fit DynamoDB and visa versa
https://docs.rs/dynomite/
MIT License
220 stars 53 forks source link

How to handle empty HashSet attributes? #152

Open danj opened 3 years ago

danj commented 3 years ago

Hi,

I'm new to Rust and Dynomite. Have some experience with DynamoDB. Hope my question makes sense.

I'd like to have an item with an attribute of type HashSet.

#[derive(Item, Debug, Clone)]
struct User {
    #[dynomite(partition_key)]
    id: String,
    friends: HashSet<String>
}

When I try to create such an item in DynamoDB it seems like the hashset is translated to an attribute of type SS with an empty set of values { "SS": [] }. This is not permitted by DynamoDB and returns an error.

Alternatively, when I define the attribute as an Option (initialized to None) the resulting Item has a NULL attribute { "NULL": true }

#[derive(Item, Debug, Clone)]
struct User {
    #[dynomite(partition_key)]
    id: String,
    friends: Option<HashSet<String>>
}

The challenge with the NULL attribute is that subsequent update expressions such as "ADD friends :v" no longer work, as the attribute type is not a Set.

Any advice / best-practices ?

Thanks,

phrohdoh commented 3 years ago

When I try to create such an item in DynamoDB it seems like the hashset is translated to an attribute of type SS with an empty set of values { "SS": [] }.

Is the serialized set always empty (regardless of the state of your HashSet<_>)? If so, that's be a bug (in dynomite).

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes.SetTypes tells us

DynamoDB does not support empty sets

Unfortunately I don't yet have sufficient relevant experience to comment further.

danj commented 3 years ago

When the HashSet<_> is not empty the serialization is correct.

The challenge is adding to an empty set. DynamoDB supports using the ADD update expression. If the set attribute exists it will add the item to the set. If it doesn't exist, dynamodb will create it.

However, in this case it's kind of a problem. We can't have an empty set (not supported by DynamoDB) and we can't not have the attribute at all either (as dynomite) always creates it.

As a workaround I ended up making sure the set is never empty. Not sure this is the best approach, but I did want to keep the attribute defined as a set in order to use the contains update-condition-expression

On Wed, Jan 20, 2021 at 9:16 PM taryn notifications@github.com wrote:

When I try to create such an item in DynamoDB it seems like the hashset is translated to an attribute of type SS with an empty set of values { "SS": [] }.

Is the serialized set always empty (regardless of the state of your HashSet<_>)? If so, that's be a bug (in dynomite).

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes.SetTypes tells us

DynamoDB does not support empty sets

Unfortunately I don't yet have sufficient relevant experience to comment further.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/softprops/dynomite/issues/152#issuecomment-763872201, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAQ5JXBXPBGKXQTJC76YHTS24TYPANCNFSM4WEGWKDA .