Open satyam8080 opened 1 year ago
PynamoDB is not set to support any particular web app framework. All we provide is an schema layer on top of DynamoDB.
If you don't need the schema, i.e. you just want to persist arbitrary JSON data, wouldn't you be better off using boto3 directly?
Table:
University { location:{ city: "New York", latitude: "40.7128° N", longitude: "74.0060° W" }, name: "MIT", other_fields:{ others: "random data" } }
If I want to update the city location from New York to California, I have to pass the complete location object otherwise rest fields will get removed and only the updated field will remain, is it possible to update only the city using pynamodb?
university.update(
actions=[UniversityModel.location.city.set("California")]
)
The above query will work but what if we don't know which field is getting updated, Is there any way to update it dynamically and without passing other fields of the location object?
You can construct it dynamically with getattr.
Hi @ikonst, can you please provide some examples of how to implement it?
Something like this (untested...):
actions = []
def update_from_dict(m, d):
for k, v in d.items():
sub_m = getattr(m, k)
if isinstance(v, dict):
update_from_dict(v, sub_m)
else:
actions.append(sub_m.set(v))
update_from_dict(UniversityModel, my_request_dict)
university.update(actions=actions)
This wouldn't cover all bases, for example it won't handle the cases when you need to create a map that didn't exist before, but that's not unique to PynamoDB -- whenever you have an "update" operation, in any kind of system, you need to decide how to handle such cases.
Thanks @ikonst, by modifying your suggested logic, I came up with a solution that handles some edge cases (like it won't handle the cases when you need to create a map that didn't exist before)
try:
uni_data = UniversityModel.get(university_id)
campus = campus.dict(exclude_none=True, exclude_unset=True)
for k, v in campus.items():
if uni_data.campus is None:
# Add new object when the campus is None
uni_data.campus = {k: v}
else:
# Find the relevant key in campus and update it with appropriate value
uni_data.campus[k] = v
uni_data.updated_at = datetime.utcnow()
uni_data.save()
return uni_data.campus.attribute_values
except UniversityModel.DoesNotExist:
return JSONResponse(status_code=404, content={"message": f"Invalid university id"})
Please review it when you can
For clarity, I would do the try-except around the uni_data = UniversityModel.get(university_id)
line only.
But overall, yes, something like this should work.
I have a University model which has some fields like campus, faculty, etc and I want to update it without manually checking or by looping over each request payload.
For Example -
`class CampusMap(DynamicMapAttribute):
`class UniversityModel(Model):
`
Now consider the request payload for updating the campus will be like this -
{ "city": "Muzaffarpur" }
Or, It can be -{ "state": "Bihar" }
So Is it any way to dynamically update the campus without checking the keys in the payload, like if the city is present then only the city will be updated, or if both city and state are present then both will be updated?
I want something like Serializers does in the case of Django + Postgres, we need to pass the payload data along with the University object.
Django example -
uni_data = University.objects.get(university_id)
new_data = UniversitySerializer(uni_data[0], request_payload_data, partial=True)
if new_data.is_valid(raise_exception=True): new_data.save()
Any similar Serializers approach is available in Pynamodb?
@ikonst