---
title: Deal with the change of field data type of PynamoDB, an ORM of DynamoDB - Best Software Development Team Extension Partner for Nordics
description: Learn how to manage and execute a change of field data type of PynamoDB efficiently for improved database schema flexibility.
image: https://www.craftsmensoftware.com/hubfs/Imported_Blog_Media/Deal-with-the-change-of-field-data-type-of-PynamoDB-an-ORM-of-DynamoDB.webp
---

[Skip to main content](https://www.craftsmensoftware.com/blog/deal-with-the-change-of-field-data-type-of-pynamodb-an-orm-of-dynamodb#main-content)

[![Craftsmen-logo](https://www.craftsmensoftware.com/hs-fs/hubfs/Website%202.png?width=200&height=72&name=Website%202.png) ![Craftsmen-logo](https://www.craftsmensoftware.com/hs-fs/hubfs/Website%202.png?width=200&height=72&name=Website%202.png) ![Craftsmen-logo](https://www.craftsmensoftware.com/hs-fs/hubfs/Website%202.png?width=200&height=72&name=Website%202.png) ![Craftsmen-logo](https://www.craftsmensoftware.com/hs-fs/hubfs/Website%202.png?width=200&height=72&name=Website%202.png)](https://www.craftsmensoftware.com)

- [About us](https://www.craftsmensoftware.com/about-us)
- [Client Stories](https://www.craftsmensoftware.com/client-success-stories)
- [How We Work](https://www.craftsmensoftware.com/how-we-work)
- [Case Study](https://www.craftsmensoftware.com/case-study)
- [Blog](https://www.craftsmensoftware.com/blog)
- [Career](https://careers.craftsmensoftware.com/)

Open main navigation

Close main navigation

- [About us](https://www.craftsmensoftware.com/about-us)
- [Client Stories](https://www.craftsmensoftware.com/client-success-stories)
- [How We Work](https://www.craftsmensoftware.com/how-we-work)
- [Case Study](https://www.craftsmensoftware.com/case-study)
- [Blog](https://www.craftsmensoftware.com/blog)
- [Career](https://careers.craftsmensoftware.com/)
- [Get In Touch](https://www.craftsmensoftware.com/contact-us)

[Get In Touch](https://www.craftsmensoftware.com/contact-us)

## Deal with the change of field data type of PynamoDB, an ORM of DynamoDB

![Deal with the change of field data type of PynamoDB, an ORM of DynamoDB](https://www.craftsmensoftware.com/hs-fs/hubfs/Imported_Blog_Media/Deal-with-the-change-of-field-data-type-of-PynamoDB-an-ORM-of-DynamoDB.webp?width=1200&height=820&name=Deal-with-the-change-of-field-data-type-of-PynamoDB-an-ORM-of-DynamoDB.webp)

Effectively manage the change of field data type of PynamoDB, an object-relational mapper (ORM) for DynamoDB. Ensure smooth database schema updates and maintain application performance and integrity with this guide.

[PynamoDB](https://pynamodb.readthedocs.io/), with a Python interface, is a great [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping) for [AWS DynamoDB](https://aws.amazon.com/dynamodb/). DynamoDB is a [NoSQL](https://en.wikipedia.org/wiki/NoSQL) database with scalability and security and it has awesome [API](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.API.html) and [SDKs](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.html). PynamoDB wraps the underneath APIs of DynamoDB and gives a beautiful [pythonic](https://www.dictionary.com/browse/pythonic) way to use DynamoDB.

In real-world our DB fields are not constant. It can change with the requirements update of our project. The hard part is when you have to maintain the old and new features. For example, a field data type can change from [String to Binary](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes). So if any API e.g. [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer) with versioning is working with DynamoDB, you have to accept both old data type (String) and new data type (Binary). We are going to find a solution in such a case.

## Setting the goal

Let’s start with setting a goal. Assume we have a field with Dynamo data type List. But after times it changes to Map. So we will do

- Accept Map object and save to DynamoDB
- Accept List object and change it to Map according to requirement and save to DynamoDB as our field changed to Map
- Return Map object according to requirement change

## Setting the project

Let’s add a couple of files to do our task.

```
# Add project folder
mkdir change-field-ddb
cd change-field-ddb
# Add Pipfile for requirements mange with pipenv
touch Pipfile
# For Custom PynamoDB attributes
touch attributes.py
# Add models.py to add pynamo model
touch models.py
# To test everything
touch test.py
```

## Add python requirements

Add following requirements to **Pipfile**

```
[dev-packages]
pipenv = "==2020.8.13"
moto = "==1.3.14"
[packages]
pynamodb = "==4.3.2"
[requires]
python_version = "3.8"
```

 

Now initiate pipenv with

```
pipenv install
```

 

Now the project will look like

```
tree
.
├── attributes.py
├── models.py
├── Pipfile
├── Pipfile.lock
└── test.py
```

 

## The changed datatype

Let’s assume our previous datatype (List) for a field **result** is

```
[3.75, 3.17, 3.90, 3.67, .......]
```

 

So the **result** stores CGPA of a student from 1st semester to final semester e.g. **result\[0\]** as 1st semester, **result\[1\]** as 2nd semester, and so on. But we will make it better (Map) at the updated version

```
{
    'semester 1': 3.75,
    'semester 2': 3.17,
    'semester 3': 3.90,
    'semester 4': 3.67,
    ..................
}
```

## PynamoDB attributes

Add the custom PynamoDB attribute to accept old (List) and new (Map) attribute and saves only as Map. But at return time it will return old (List) data as Map and also new data as Map. Also, we are going to use custom **UUIDAttribute** which will be used as a hash key.

```
 
```

\# attributes.py  
import uuid  
import pynamodb.attributes  
\# UUID  Attribute will use as Dynamo hash key  
class UUIDAttribute(pynamodb.attributes.UnicodeAttribute):  
    def serialize(self, value):  
        return super().serialize(str(value))  
    def deserialize(self, value):  
        return uuid.UUID(super().deserialize(value))  
\# Add custom attribute to serialize and deserialize data  
class ResultAttribute(pynamodb.attributes.MapAttribute):  
    @classmethod  
    def is\_raw(cls):  
        # Set to use as AttributeContainer  
        # https://pynamodb.readthedocs.io/en/latest/api.html#pynamodb.attributes.MapAttribute  
        return True  
    @staticmethod  
    def \_parse\_value(values):  
        return {  
            f'semester {idx+1}': val for idx, val in enumerate(values)  
        }  
    def serialize(self, values):  
        # Convert python list to native pynamo  
        if isinstance(values, (list, tuple)):  
            values = self.\_parse\_value(values)  
        return super().serialize(values)  
    def get\_value(self, value):  
        try:  
            # Convert from  
            # {'L': \[{'N': '3.75'}, {'N': '3.17'}\]}  
            # to  
            # {'M': {'semester 1': {'N': '3.75'}, 'semester 2': {'N': '3.17'}}}  
            value = {'M': self.\_parse\_value(value\['L'\])}  
        except (KeyError, TypeError):  
            pass  
        return super().get\_value(value)

 Copy

## The PynamoDB Model

We are going to start with a simple PynamoDB Model only with 2 fields

```
 
```

\# models.py  
import uuid  
import pynamodb.models  
import pynamodb.attributes  
from attributes import UUIDAttribute, ResultAttribute  
class ResultModel(pynamodb.models.Model):  
    id = UUIDAttribute(hash\_key=True, default=uuid.uuid4)  
    result = ResultAttribute()  
    class Meta:  
        table\_name = "test-ddb-table"

 Copy

## Time to Test

Add some tests in test.py

from decimal import Decimal  
from decimal import Decimal  
import boto3  
import moto  
from models import ResultModel  
with moto.mock\_dynamodb2():  
    region = 'eu-west-1'  
    ResultModel.Meta.region = region  
    ResultModel.create\_table(wait=True)  
    # Data  
    result\_map = {  
        'semester 1': 3.75,  
        'semester 2': 3.17,  
        'semester 3': 3.90,  
        'semester 4': 3.67  
    }  
    result\_list = \[3.75, 3.17, 3.90, 3.67\]  
    # Insert as Map with PynamoDB  
    result1 = ResultModel(result=result\_map)  
    result1.save()  
    assert ResultModel.count() == 1  
    result1\_id = result1.id  
    print(result1\_id)  
    # Retrieve the data from inserted as list  
    result1\_retr = ResultModel.get(result1\_id)  
    assert result1\_retr.result.attribute\_values == result\_map  
    # Insert as list so it will convert and saved as map  
    result2 = ResultModel(result=result\_list)  
    result2.save()  
    assert ResultModel.count() == 2  
    result2\_id = result2.id  
    print(result2\_id)  
    # Retrieve the data from inserted as list  
    result2\_retr = ResultModel.get(result2\_id)  
    assert result2\_retr.result.attribute\_values == result\_map  
    # Insert list value in result with boto3  
    dynamodb = boto3.resource('dynamodb', region)  
    table = dynamodb.Table(ResultModel.Meta.table\_name)  
    # float is not supported by boto3. But decimal is supported. So converted to Decimal  
    item = \[Decimal(str(v)) for v in result\_list\]  
    # Updating item instead of creating because result is MapAttribute by default  
    table.update\_item(  
        Key={'id': str(result1\_id)},  
        AttributeUpdates={  
            'result': {'Value': item, 'Action': 'PUT'}  
        }  
    )  
    assert table.get\_item(Key={'id': str(result1\_id)})\['Item'\]\['result'\] == item  
    # Retrieve the data that is a list in dynamodb  
    result1\_retr = ResultModel.get(result1\_id)  
    assert result1\_retr.result.attribute\_values == result\_map

 Copy

```
 
```

Run tests with

```
pipenv shell
python3 test.py
```

Full code can be found here:  
[https://github.com/melon-ruet/change-field-ddb](https://github.com/melon-ruet/change-field-ddb)

![Mahabubur Rahaman Melon](https://www.craftsmensoftware.com/hs-fs/hubfs/Mahabubur%20Rahaman%20Melon.png?width=120&height=120&name=Mahabubur%20Rahaman%20Melon.png)

Author: **[Mahabubur Rahaman Melon](https://www.craftsmensoftware.com/blog/author/mahabubur-rahaman-melon)**  
 18/04/2024

 Software Development Engineer

![Hire AI-Native Engineers](https://www.craftsmensoftware.com/hubfs/Z63_3132.webp)

## Hire AI-Native Engineers

[![Book A Strategy Call](https://www.craftsmensoftware.com/hubfs/Book%20A%20Strategy%20Call.svg)](https://www.craftsmensoftware.com/contact-us)

### **About Craftsmen**

[The Team](https://www.craftsmensoftware.com/about-us)

[Our Partnership Model](https://www.craftsmensoftware.com/how-we-work)  
[Career](https://careers.craftsmensoftware.com/)

[FAQ](https://www.craftsmensoftware.com/frequently-asked-questions-faq)  
[Privacy Policy](https://www.craftsmensoftware.com/privacy-policy-best-software-development-company-in-bangladesh) 

[Craftsmen LinkedIn Page](https://linkedin.com/company/craftsmensoftware)   [Craftsmen Facebook Page](https://www.facebook.com/craftsmenltd/)   [Craftsmen Youtube Page](https://www.youtube.com/@craftsmensoftware)

### **Headquarter**

**Craftsmen UK**  
One Sovereign Quay, Bridge End, Leeds, West Yorkshire LS1 4AG United Kingdom 

**Operational Hub

Craftsmen Bangladesh**  
Plot # 316, Lane # 4, DOHS Baridhara,

Dhaka - 1206, Bangladesh

### **Sales & Partnership Offices**

**Craftsmen Norway**  
Kong Oscars gate 66, 68, 5017 Bergen, Norway

**Craftsmen France**  
6 Avenue Pierre Grenier, 92100 Boulogne-Billancourt, Paris, France

### **A Team You Can Trust**

#### [![ISO Certificates New](https://www.craftsmensoftware.com/hs-fs/hubfs/ISO%20Certificates%20New.png?width=300&height=96&name=ISO%20Certificates%20New.png)](https://www.craftsmensoftware.com/trust-centre)

[![glassdoor (1)](https://www.craftsmensoftware.com/hs-fs/hubfs/glassdoor%20(1).png?width=110&height=79&name=glassdoor%20(1).png)](https://www.glassdoor.com/Overview/Working-at-Craftsmen-EI_IE3004266.11,20.htm) [![goodfirms.co](https://www.craftsmensoftware.com/hs-fs/hubfs/goodfirms.co.webp?width=110&height=95&name=goodfirms.co.webp)](https://www.craftsmensoftware.com/blog/craftsmen-thrives-at-goodfirms-by-offering-scalable-robust-software-solutions-developed-with-quality-by-maestros)

 

 © 2026 Craftsmen. All rights reserved.

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Mahabubur Rahaman Melon",
    "url" : "https://www.craftsmensoftware.com/blog/author/mahabubur-rahaman-melon"
  },
  "dateModified" : "2026-04-30T08:11:08.996Z",
  "datePublished" : "2024-04-17T22:45:00.000Z",
  "headline" : "Deal with the change of field data type of PynamoDB, an ORM of DynamoDB - Best Software Development Team Extension Partner for Nordics",
  "image" : [ "https://www.craftsmensoftware.com/hubfs/Imported_Blog_Media/Deal-with-the-change-of-field-data-type-of-PynamoDB-an-ORM-of-DynamoDB.webp" ],
  "mainEntityOfPage" : {
    "@id" : "https://www.craftsmensoftware.com/blog/deal-with-the-change-of-field-data-type-of-pynamodb-an-orm-of-dynamodb",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://www.craftsmensoftware.com/hubfs/Craftsmen%20Logo_Black.png"
    },
    "name" : "Craftsmen Ltd."
  }
}
```

```json
{
  "@context" : "https://schema.org",
  "@type" : "SoftwareCompany",
  "address" : [ {
    "@type" : "PostalAddress",
    "addressCountry" : "Norway",
    "addressLocality" : "Oslo"
  }, {
    "@type" : "PostalAddress",
    "addressCountry" : "United Kingdom",
    "addressLocality" : "London"
  }, {
    "@type" : "PostalAddress",
    "addressCountry" : "France",
    "addressLocality" : "Paris"
  }, {
    "@type" : "PostalAddress",
    "addressCountry" : "United States",
    "addressLocality" : "New York"
  }, {
    "@type" : "PostalAddress",
    "addressCountry" : "Bangladesh",
    "addressLocality" : "Dhaka"
  } ],
  "areaServed" : [ {
    "@type" : "Country",
    "name" : "Norway"
  }, {
    "@type" : "Country",
    "name" : "Sweden"
  }, {
    "@type" : "Country",
    "name" : "United Kingdom"
  }, {
    "@type" : "Country",
    "name" : "France"
  }, {
    "@type" : "Country",
    "name" : "United States"
  }, {
    "@type" : "Country",
    "name" : "Bangladesh"
  } ],
  "description" : "Trusted AI-native engineering partner providing software team extension, IT staff augmentation, and dedicated developer teams globally.",
  "logo" : "https://www.craftsmensoftware.com/hubfs/logo.png",
  "name" : "Craftsmen Software",
  "url" : "https://www.craftsmensoftware.com"
}
```