How to ensure backwards compatibility when changing data type of attribute DynamoDB

612 Views Asked by At

I am attempting to change the data type of an attribute in one of my DDB tables, but because this data is read from and written to, altering the data type of the attribute causes subsequent read failures when reading old records, which look like this:

could not unconvert attribute
DynamoDBMappingException: expected M in value {N: 1000,}

My question is about how I can change the data type of an attribute in my table, and architect the change such that I can still read the Double value that exists in previous records. Here is the class in question:

@DynamoDBTable(tableName = "Sections")
@Data
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class SectionRecord {
    @DynamoDBHashKey
    private String id;
    private Map<String, Double> sectionTarget; //previous definition: private Double sectionTarget;
    
    public void setSectionTarget(Double sectionTarget, String key) {
       if (this.sectionTarget == null) {
          this.sectionTarget = new HashMap<Double, String>();
       }
       this.sectionTarget.put(key, sectionTarget);
    }
    
    public void getSectionTarget(String key) {
       return this.sectionTarget.get(key);
    }

}

And eventually, I try to read a record like this:

mapper.load(SectionRecord.class, id);

Which is presumably where the issue comes from - I'm trying to read a Double (which exists in the ddb currently) as a map (the changes I've made to the attribute).

I'd love to hear some guidance on how best to architect such a change such that these backwards compatibility issues could be mitigated.

1

There are 1 best solutions below

0
On

You have to

  • Create a new attribute with the new type, both in dynamo and in SectionRecord
  • Your code should be able to read and work with both
  • deploy it on production and wait for the old data to disappear (or create a custom migration logic)
  • Delete the old field, the logic can now rely only on the new field

Welcome to dynamo where you don't have DB migrations :(