【问题标题】:Create if doesn't exist如果不存在则创建
【发布时间】:2012-02-04 16:15:40
【问题描述】:

我有一个 Django 应用程序,它从 Web API 读取数据并将其放入数据库中。
有没有办法从模式创建新对象但如果对象已经存在则防止重复异常?

换句话说,有没有办法保存一个对象,但如果它已经存在则什么都不做?

【问题讨论】:

    标签: django models


    【解决方案1】:

    【讨论】:

    • 使其成为文档的链接会添加一些字符(我猜它是一个更好的答案)
    • 这似乎做了 2 个查询。如果我只想保存对象以防它不存在,有没有办法只使用 1 个查询?我猜想捕获IntegrityError 会导致当前事务中止并且还不够。
    • 如果添加保存点,您可以捕获完整性错误,例如使用transaction.atomic(确保你在atomic块的外部捕获,即try: with acomic: create; except IntegrityError。确保你没有捕获其他完整性错误也很棘手你打算的那个
    • 如果你能捕捉到IntegrityError,我的测试表明,与get_or_create()相比,当记录存在时,它的执行时间几乎减少了一半。
    【解决方案2】:

    在 Django 1.7 中,你也可以这样做:

    Model.objects.update_or_create()

    【讨论】:

    • 我真的可以在 1.6 中使用它。
    【解决方案3】:

    看起来在较新版本的 Django 中,save() 函数默认执行 UPDATE 或 INSERT。见here

    【讨论】:

    • 看起来它应该自动选择好,但是在我的数据库中,每次我运行我的脚本来填充数据库时,它都会复制条目。
    • save() 方法检查模型的 PK 是否有值。作者必须查询数据库以获得具有正确 PK 的模型实例才能使用此技术。单独使用 save() 并不能发挥作用。
    【解决方案4】:

    可以使用Model.objects.get_or_create()实现

    示例

    obj, created = Person.objects.get_or_create(
        first_name='John',
        last_name='Lennon',
        defaults={'birthday': date(1940, 10, 9)},
    )
    

    传递给 get_or_create() 的任何关键字参数(此处为 first_namelast_name)——除了一个名为 defaults 的可选参数——将用于在数据库中查询(查找对象)。

    它返回一个元组,如果找到一个对象,get_or_create() 返回该对象的一个​​元组,返回False。

    注意:同样的事情也可以使用try except 语句实现
    示例:

    try:
        obj = Person.objects.get(first_name='John', last_name='Lennon')
    except Person.DoesNotExist:
        obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
        obj.save()
    

    【讨论】:

      猜你喜欢
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      • 2020-08-18
      • 2021-05-02
      • 2010-09-19
      • 2011-03-20
      • 2010-12-03
      • 2020-12-08
      相关资源
      最近更新 更多