2011-11-18 39 views
3

我来自一个MySQL背景的地方,如果我想插入一条记录,我可以使用INSERT ignore命令,让我可以在短短塞行,如果有冲突只是忽略它。的Django和PostgreSQL和IntegrityErrors

现在,有了一个Django项目我的工作,我使用PostgreSQL,并发出多个保存在一个循环。不过,我想如果我得到一个IntegrityError(这我忽略了,见下面的代码),然后我失去我试图插入对象的负荷。我应该怎么解决这个问题:

for thing in things: 
    try: 
     #potentially dangerous save.. 
     obj = Thing(stuff=10) 
     obj.save() 
    except IntegrityError: 
     pass 

如果说,在第5步循环发生IntegrityError,哪些对象将被插入到数据库中?

回答

7

这取决于你如何管理你的交易。

上的Postgres如果交易查询的一个发生故障,所有后续查询也将失败,错误“当前事务被中止,忽略查询直到事务块的结束”。

要对付它,你应该在使用transaction.savepoint_rollback except块。

请参阅Django的文档Handling exceptions within PostgreSQL transactions

它给人的下一个例子

a.save() # Succeeds, and never undone by savepoint rollback 
try: 
    sid = transaction.savepoint() 
    b.save() # Could throw exception 
    transaction.savepoint_commit(sid) 
except IntegrityError: 
    transaction.savepoint_rollback(sid) 
c.save() # Succeeds, and a.save() is never undone 
+0

感谢,心动不如行动! – Stuart

1

通过不忽略错误?

你写的代码有点像这样。

You: Save all the things. 
Django: You're about to violate data integrity in your database. 
You: I don't care. 
Django: I can't simply corrupt your data. I'll just throw away 
     the things that would corrupt your data. 
You: That's what I wanted. 

虽然这可能适用于某些应用程序,但它不适用于大多数应用程序。

你只需要决定你应该与侵犯了您的完整性约束的数据做什么,你需要修正导致让坏的数据去摆在首位的save()方法的代码。关于Form and Field Validation的文档可能会有所帮助。