How to roll back related objects if any error happened.

23 views
Skip to first unread message

Sencer Hamarat

unread,
Jul 4, 2022, 7:18:00 AM7/4/22
to django...@googlegroups.com
Hi,

Say I have a parent and a child model. 

And also there is a view which is using DRF serializers to save data into models.

The saving operation steps are:

First create parent parent object
Then, create child object with parent object relation.

The view code regarding the description above:

parent_data = {
    "foo": "bar",
    "baz": "bar"
}

parent_serializer = ParentSerializer(data=parent_data)
if parent_serializer.is_valid():
    parent_serializer.save()

    child_data = {
        "parent_id": parent_serializer.data['id'],
        "baz": "foo":
        "bar": "baz"
    }

    child_serializer = ChildSerializer(data=child_data)
    if child_serializer.is_valid():
        child_serializer.save()


if any exception is thrown while child_serializer saving, how to roll back the parent object, too?

Is there any chance to make this happen in a transaction to roll back any related record?


Kind regards,
Sencer HAMARAT

Ryan Nowakowski

unread,
Jul 4, 2022, 12:59:27 PM7/4/22
to django...@googlegroups.com

Sencer Hamarat

unread,
Jul 5, 2022, 7:46:18 AM7/5/22
to django...@googlegroups.com
Hi,

I tried that but, when child_serializer.save() throws an exception, the row created by parent_serializer.save() at the database is not rolled back.

Kind regards,
Sencer HAMARAT



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/BEE4B516-7426-4A07-B91B-9733537D4F92%40fattuba.com.

Antonis Christofides

unread,
Jul 5, 2022, 8:49:49 AM7/5/22
to django...@googlegroups.com

Could you show the code with your attempt to use atomic?

Sencer Hamarat

unread,
Jul 5, 2022, 10:18:24 AM7/5/22
to django...@googlegroups.com
Hi Antonis,

The code that I tried is something like below:

with transaction.atomic():
    parent_data = {
        "foo": "bar",
        "baz": "bar"
    }

    parent_serializer = ParentSerializer(data=parent_data)
    if parent_serializer.is_valid():
        parent_obj = parent_serializer.save()

        child_data = {
            "parent_id": parent_obj.id,
            "baz": "foo":
            "bar": "baz"
        }

        child_serializer = ChildSerializer(data=child_data)
        if child_serializer.is_valid():
            child_obj = child_serializer.save()


As I mentioned in the previous email;
If child_serializer.save() raises an exception, the db row created by parent_serializer.save() is not rolled back.

Actually, I changed the way I send the data to the db. I put the child data as a nested json, 
wrote a create method in the serializer and pushed the data through a single serializer to the db.
Thus, any bad request at the serializer validation level is avoided and there is no need to go back.

Anyway, If you think that my claim above is false, I would like to hear your opinion.


Kind regards,
Sencer HAMARAT



Antonis Christofides

unread,
Jul 5, 2022, 2:39:13 PM7/5/22
to django...@googlegroups.com

I'm not really an expert, but it strikes me that this doesn't work. If you are using MySQL or SQLite, make sure you read the Database-specific notes on Database transactions in the Django documentation. If you want further help on this, please post your DATABASES setting.

Regards,

Antonis

Reply all
Reply to author
Forward
0 new messages