【问题标题】:Using transaction to ensure 2 models save or neither save使用事务确保 2 个模型保存或不保存
【发布时间】:2013-03-06 22:39:25
【问题描述】:

我需要确保 Model1 和 Model2 都保存或都不保存,我很确定我应该能够在事务中执行此操作,但它似乎不起作用。

我不确定我是否了解交易如何正常运作。我认为该事务对于包装在装饰器中的整个函数调用是有益的。

我也不确定这是否只是一个 Sqlite 问题。

models.py

​​>
from django.db import models
class Model1( models.Model ):
    name = models.CharField( max_length = 20 )
    number = models.IntegerField( )

class Model2( models.Model ):
    name = models.CharField( max_length = 20 )
    number = models.IntegerField( )
    parent = models.ForeignKey( Model1 )

示例交易代码

from django.db import transaction

@transaction.commit_manually
def somefunction( name ):
    try:
        a = Model1.objects.get( name = name )
    except Model1.DoesNotExist:
        a = Model1( name = name )

    try:
        b = Mode2.objects.get( name = name)
    except Model2.DoesNotExist:
        b = Model2( name = name )

    a.number = 3
    b.number = 'a'

    try:
        a.save()
        b.parent = a
        b.save()
        transaction.commit()
    except:
        transaction.rollback()

我没有尝试过 MySQL 或 Postgres,因为我实际上并没有发现任何具体说明 Sqlite 不能做到这一点的东西,所以只想看看我做错了什么,或者它确实是 Sqlite3。

【问题讨论】:

  • 你应该考虑使用get_or_create
  • get_or_create 会创建对象,如果第二个对象创建失败,我不希望创建它。
  • 我认为 django 会自行回滚错误的提交
  • 好吧,我不明白你为什么要这样做。为什么不把name 变成unique
  • 我只是想确保两个模型都已保存或都不保存。它实际上与 Model.name 字段或字段的唯一性无关。 Django 确实会自动提交,但它会为单个模型保存不超过 2 个模型。

标签: django sqlite transactions


【解决方案1】:

所以最终的答案是事务工作正常,只是我的单元测试没有继承自

https://docs.djangoproject.com/en/1.2/topics/testing/#django.test.TransactionTestCase

由于我只是从 TestCase 继承,每个 test_ 方法都包装在一个事务中,我无法控制 .commit() 或 .rollback() 行为。

这只是我完全没有意识到测试用例是如何运行的。

【讨论】:

  • 哦,你应该提到这是在单元测试中完成的:P
  • 是的,这是我的错误假设
猜你喜欢
  • 1970-01-01
  • 2013-11-23
  • 2022-01-03
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多