我想创建和对象,将其保存到DB,然后检查DB上是否有另一行,token
execution_time
= 0。如果有,我想删除创建的对象,然后重新启动该过程。
transfer = Transfer(token = generateToken(size=9))
transfer.save()
while (len(Transfer.objects.filter(token=transfer.token, execution_time=0))!=1):
transfer.delete()
transfer = Transfer(token = generateToken(size=9))
transfer.save()
我是否需要在每个循环之间提交事务?例如,在每个循环结束时调用commit()
?
while (len(Transfer.objects.filter(token=transfer.token, execution_time=0))!=1):
transfer.delete()
transfer = Transfer(token = generateToken(size=9))
transfer.save()
commit()
@transaction.commit_manually
def commit():
transaction.commit()
答案 0 :(得分:0)
根据您的描述,我认为您不需要使用交易。您基本上是使用代码手动重新创建事务回滚。
我认为处理此问题的最佳方法是让数据库约束强制执行此问题。 token
和execution_time
应该是唯一的吗?在这种情况下,您可以使用unique_together
在Django中定义约束。如果约束是token
在execution_time
为0
时应该是唯一的,那么某些数据库也允许您定义类似的约束。
如果约束在数据库中,您可以在循环中执行get_or_create()
,直到Transfer
为created
。
如果由于某种原因无法在数据库中定义约束,那么我认为您的版本可以正常工作。 (一个改进是使用.count()
而不是len
。)
答案 1 :(得分:0)
我想创建和对象,将其保存到DB,然后检查是否存在 DB上的另一行,具有相同的令牌,执行时间= 0。如果 有,我想删除创建的对象然后重新启动 过程
根据您的最终目标,您可以采用几种方法:
您是否希望在编写时不会写入其他记录(以防止重复?)如果是这样,您需要锁定表,并且为此,您需要执行原子交易,@transaction.atomic
(1.6中的新内容)
如果要确保在给定字段组合的情况下不创建重复记录,则需要在数据库级别使用unique_together
我相信结合上述两个可以解决你的问题;但是,如果你想要更强力的方法;您可以覆盖对象的save()
方法,然后在尝试创建(或更新)违反约束的记录时引发相应的异常。
在您的视图中,您将捕获此异常,然后采取适当的操作。