大型模型对象列表上的 Django 1.6 事务管理
Django 1.6 Transaction Management on large list of Model Objects
长问短:如果我需要遍历模型对象列表并单独保存它们,我不确定该怎么做。
要正确理解这一点,
假设,我的模型名称 = Foo
示例:
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
}
现在我想做的是改变:
name for (Foo 1)
alias for (Foo 2)
description for (Foo 3)
然后通过循环手动执行更新(保存)每个对象的事务。
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
以下哪项是首选方法(实际上可能可行)?
bulk_update_internal(foo_list)
OR
bulk_update_decorated(foo_list)
................................................ ...
我有大量数据需要 save/update。
早些时候我在循环并保存它们,但没有
看起来是个好主意。
不能使用update(),因为我希望每个数据点都是
存储不同的信息,分开保存。
编辑:预期用途
我打算做的是,通过使用 CELERY,更新 list of model objects
。所以我循环遍历列表
for update_this in bulky: update_this.save()
这意味着为所有对象调用save
方法,并且由于 Django 1.6 是自动提交的,这意味着对象在循环中保存在数据库中。坏主意。
那么,using transaction.atomic()
会帮我吗?
它会以 autocommit = 0
开始,然后 loop exit
会 commit
到数据库 ?
对于芹菜,我想在 soft time limit
到达之前使用 sid
来保存对象。这会是一个好策略吗?
使用bulk_update_decorated
版本。但据我所知,你不需要对保存点做些什么。仅来自函数的 return 和整个事务将被提交。
@transaction.atomic
def bulk_update_decorated(bulky):
try:
for update_this in bulky:
update_this.save()
except SoftTimeLimitExceeded:
pass
保存点用于事务的部分回滚。你不做任何回滚,所以在这里使用保存点没有意义。
长问短:如果我需要遍历模型对象列表并单独保存它们,我不确定该怎么做。
要正确理解这一点,
假设,我的模型名称 = Foo
示例:
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
}
现在我想做的是改变:
name for (Foo 1)
alias for (Foo 2)
description for (Foo 3)
然后通过循环手动执行更新(保存)每个对象的事务。
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
以下哪项是首选方法(实际上可能可行)?
bulk_update_internal(foo_list)
OR
bulk_update_decorated(foo_list)
................................................ ...
我有大量数据需要 save/update。
早些时候我在循环并保存它们,但没有 看起来是个好主意。
不能使用update(),因为我希望每个数据点都是 存储不同的信息,分开保存。
编辑:预期用途
我打算做的是,通过使用 CELERY,更新 list of model objects
。所以我循环遍历列表
for update_this in bulky: update_this.save()
这意味着为所有对象调用save
方法,并且由于 Django 1.6 是自动提交的,这意味着对象在循环中保存在数据库中。坏主意。
那么,using transaction.atomic()
会帮我吗?
它会以 autocommit = 0
开始,然后 loop exit
会 commit
到数据库 ?
对于芹菜,我想在 soft time limit
到达之前使用 sid
来保存对象。这会是一个好策略吗?
使用bulk_update_decorated
版本。但据我所知,你不需要对保存点做些什么。仅来自函数的 return 和整个事务将被提交。
@transaction.atomic
def bulk_update_decorated(bulky):
try:
for update_this in bulky:
update_this.save()
except SoftTimeLimitExceeded:
pass
保存点用于事务的部分回滚。你不做任何回滚,所以在这里使用保存点没有意义。