在Django 1.8中创建多个对象,而不会多次点击数据库

在Django 1.8中创建多个对象,而不会多次点击数据库,django,database,transactions,atomicity,Django,Database,Transactions,Atomicity,使用Django 1.8,如何在单个db事务中创建多个对象并写入db 以前的版本似乎已经手动设置了@commit_。但是当我试图修改这段代码时:我得到了一个异常 django.db.transaction.TransactionManagementError: The outermost 'atomic' block cannot use savepoint = False when autocommit is off. 在我看到的许多帖子中都说要用“with transaction.atom

使用Django 1.8,如何在单个db事务中创建多个对象并写入db

以前的版本似乎已经手动设置了@commit_。但是当我试图修改这段代码时:我得到了一个异常

django.db.transaction.TransactionManagementError: The outermost 'atomic' block cannot use savepoint = False when autocommit is off.
在我看到的许多帖子中都说要用“with transaction.atomic()”块包装,但这会影响每个循环中的db

这是我的代码的简化版本。我还没有运行它,但它应该显示我正在尝试做什么

class Foo(models.Model):
    Name = models.CharField( max_length=200 )

class Bar(models.Model):
    Foos = models.ManyToManyField( foo )

class Processor(object):
    def run(self,):
        myBar = Bar.object.create()

        myList = ['a', 'b', 'c', 'd']

        if True:
            set_autocommit( False )

            for char in myList:
                myFoo = Foo.objects.create(Name=char)
                myBar.Foos.add( myFoo )

            commit()
            set_autocommit( True )

我正在尝试进行所有这些更改,只对数据库进行一次修改。我知道有model.objects.bulk_创建,但我找不到处理m2m关系的方法。另外,bulk_create不会返回数据库实例的值,因此我必须将它们从数据库中拉出,用于m2m关系。

您不能在一个查询中完成所有查询。然而,你在正确的轨道上。您应该使用for batch insertion,然后再进行一次查找,将它们作为对象返回,以便添加到
foos

如果您过于担心后一个查询执行缓慢,可以设置
unique=True
或,
db_index=True
,以提高性能

您还希望使用事务维护操作的原子性,以便任何
INSERT
失败时,都应回滚:

from django.db import transaction

class Foo(models.Model):
    name = models.CharField(max_length=200, unique=True)

class Bar(models.Model):
    foos = models.ManyToManyField(Foo)

class Processor(object):
    def run(self):
        transaction.set_autocommit(False)
        try:
            myList = ['a', 'b', 'c', 'd']
            Foo.objects.bulk_create([Foo(n) for n in myList])

            myBar = Bar.object.create()
            myBar.foos.add(Foo.objects.filter(name__in=myList))
        except:
            transaction.rollback()
            raise
        else:
            transaction.commit()
        finally:
            transaction.set_autocommit(True)

有关行为的更多信息,请参阅Django文档。

我读过这篇文章,它似乎说,如果关闭自动事务,那么db写入在提交之前不会发生。为什么这不可能@brian,因为这就是事务的用途。如果您必须执行批量更新或创建,您总是希望一次将它们全部写入数据库,或者在其中一个失败时恢复。你到底想做什么?我有很多m2m关系需要填写。我正试着把他们聚在一起,把他们带进数据库。我刚刚发布了以下内容: