PynamoDB icon indicating copy to clipboard operation
PynamoDB copied to clipboard

Custom attribute with both NUMBER and BOOL values

Open Shogo1222 opened this issue 6 months ago • 1 comments

Hi,

How can I create a custom attribute that contains both number and BOOL values? NUMBER may have been mixed up with past data in the same attribute in DynamoDB. I would like to read all the numbers and BOOL values in DynamoDB and convert them to BOOL.

However, the attr_type must be specified, and it can only be either BOOL or number. I would appreciate it if you could tell me how to resolve this issue.

DynamoDB:

{'value': {'N': '0'}}
{'value': {'BOOL': '0'}}

CustomAttribute:

class CustomAttribute(Attribute):
    def serialize(self, value):
        if value is None:
            return None
        elif value:
            return True
        else:
            return False

    def deserialize(self, value):
        if value is None:
            return None
        elif isinstance(value, bool):
            return bool(value)
        elif isinstance(value, str):
            return bool(json.loads(value))

https://github.com/pynamodb/PynamoDB/blob/e8d3bb4d9b067a06b7895eaefa3c8a20d0d233b1/pynamodb/attributes.py#L194

I see here that it may not be supported, but if there is another way, please let me know.

Thanks.

Shogo1222 avatar Jan 09 '24 03:01 Shogo1222

I haven't tested it out, but looking at the source, will overriding BooleanAttribute's get_value work?

class CustomAttribute(BooleanAttribute):
  def get_value(self, value: Dict[str, Any]) -> Any:
      if 'N' in value:
         value = {'B': bool(value['N'])}
      return super().get_value(value)

ikonst avatar Jan 18 '24 03:01 ikonst