HENNGE / aiodynamo

Asynchronous, fast, pythonic DynamoDB Client
https://aiodynamo.readthedocs.io/
Other
69 stars 20 forks source link

Empty-set safety #145

Open ojii opened 1 year ago

ojii commented 1 year ago

aiodynamo used to be empty-string-safe when DynamoDB didn't support empty string values. This mercifully got fixed in DynamoDB, but DynamoDB still doesn't accept empty sets (NS, SS, BS). There's an argument to be made that aiodynamo should handle this automatically, converting F("some_set").set(set()) to F("some_set").remove(), possibly with a warning.

dimaqq commented 1 year ago

Is that what amazing dunamo db does? Let's say if there's an item with a set with 1 element and later that element is removed.

ojii commented 1 year ago

Is that what amazing dunamo db does? Let's say if there's an item with a set with 1 element and later that element is removed.

this test fails for the .set(...) case, but succeeds for the .delete(...) case. Meaning, DynamoDB is seemingly okay with empty sets so long as they have previously had values in them, just not creating new ones. Absolutely baffling.

@pytest.mark.parametrize("op", [F("set").set(set()), F("set").delete({"a"})])
async def test_empty_set(client: Client, table: TableName, op):
    await client.put_item(table, {"h": "h", "r": "r", "set": {"a"}})
    await client.update_item(table, {"h": "h", "r": "r"}, op)

EDIT: Actually, F("set").delete({"a"}) causes the key to be removed from the item 😱

ojii commented 1 year ago

🤔 this gets even more complicated because of F.set_if_not_exists which doesn't have an equivalent for empty sets from what I can see (eg "remove_if_not_exists")