Reputation: 2695
Long question short : If I would need to loop through list of Model Objects, and save them individually, I am unsure how to go about that.
To understand this correctly,
Assuming, my Model Name = Foo
example :
Model Object :
f1 = Foo 1 {
name : foo,
alias : Fooo 1,
description : Fooo 1
}
f2 = Foo 2 {
name : foo_2,
alias : Fooo,
description : Fooo 2
}
f3 = Foo 3 {
name : foo_3,
alias : Fooo 3,
description : Fooo
}
Now what I would like to do is change :
name for (Foo 1)
alias for (Foo 2)
description for (Foo 3)
and then manually do the transaction of updating (saving) each object via looping.
foo_list = list()
f1.name = 'foo_1'
foo_list.append(f1)
f2.alias = 'Foo 2'
foo_list.append(f2)
f3.description = 'Fooo 3'
foo_list.append(f3)
@task()
@transaction.atomic()
def bulk_update_decorated(bulky):
"""
:param bulky: model object list
:return: True
"""
sid = None
try:
for update_this in bulky:
update_this.save() # transaction is having an element
sid = transaction.savepoint()
return True
except SoftTimeLimitExceeded:
transaction.savepoint_commit(sid) # on loop exit commit
@task()
def bulk_update_internal(bulky):
"""
:param bulky: model object list
:return: True
"""
sid = None
try:
with transaction.atomic():
for update_this in bulky:
update_this.save()
sid = transaction.savepoint()
except SoftTimeLimitExceeded:
transaction.savepoint_commit(sid) # on loop exit commit
Which of the following is the preferred way to go (actually which might work) ?
bulk_update_internal(foo_list)
OR
bulk_update_decorated(foo_list)
................................................
I am having quite a large set of data which I want to save/update.
Earlier I was looping through and saving them, which did not seem like a good idea.
Can't use update(), because I want each data point to be storing different information and saved separately.
Edit : Intended use
What I intended to do was, via using CELERY, update the list of model objects
. So I was looping over the list like
for update_this in bulky: update_this.save()
This would mean save
method be called for all the objects, and since Django 1.6 is autocommit, this would mean objects are saved in database in a loop. Bad Idea.
So, using transaction.atomic()
would help me here right ?
It would start with autocommit = 0
and on loop exit
would commit
to database ?
for celery i wanted to use sid
to hold objects before soft time limit
would be reached. This would be a good strategy ?
Upvotes: 0
Views: 219
Reputation: 45575
Use the bulk_update_decorated
version. But as far as I understand you don't need to do something with savepoints. Just return from the function and whole transaction will be committed.
@transaction.atomic
def bulk_update_decorated(bulky):
try:
for update_this in bulky:
update_this.save()
except SoftTimeLimitExceeded:
pass
Savepoints are used to partial rollback of transaction. You don't do any rollbacks so using of savepoint makes no sense here.
Upvotes: 1