【问题标题】:generate update query using django orm使用 django orm 生成更新查询
【发布时间】:2013-02-25 12:36:10
【问题描述】:

我需要使用 django orm 来实现这个查询:

update table set field=field+1 where id=id

我不想用这个:

o = model.objects.get(id=id)
o.field+=1
o.save()

因为它使用 select 和 when update,而不是线程安全的。

如何通过 orm 实现?

【问题讨论】:

    标签: python django orm sql-update


    【解决方案1】:

    对于django v 2.2(可能还有3+)SQL语句编译功能可以是:

    from django.db.models.sql.subqueries import UpdateQuery
    
    def compile_update_query(query_set, update_kwargs):
        query = query_set.query.chain(UpdateQuery)
        query.add_update_values(update_kwargs)
        return str(query)
    

    其中query_setMyShinyModel.objects.filter(id=42)update_kwargs 是要更新的模型字段字典

    【讨论】:

      【解决方案2】:

      如果您需要将UPDATE ORM 查询转换UPDATE SQL 语句而不执行它

      update() 方法立即应用并返回查询匹配的行数 (django 1.8 docs)

      def generate_update_sql(queryset, update_kwargs):
          """  [checked on django 1.8]
          Converts queryset with update_kwargs
          like if was: queryset.update(**update_kwargs)
          """
          from django.db.models import sql
      
          query = queryset.query.clone(sql.UpdateQuery)
          query.add_update_values(update_kwargs)
          compiler = query.get_compiler(queryset.db)
          sql, params = compiler.as_sql()
          return sql % params
      

      用法

      qs = Event.objects.exclude(app='some')
      update_kwargs = dict(description='test', action='action')
      generate_update_sql(qs, update_kwargs) 
      

      会回来

      UPDATE `api_event` SET `description` = test, `action` = action WHERE NOT (`api_event`.`app` = some)
      

      【讨论】:

        【解决方案3】:

        您可以使用update,详情请见the documentation

        【讨论】:

        • OP 希望以线程安全的方式根据现有字段更新属性,这是由 F() 表达式完成的。我不认为更新有这样的功能。你确定吗?
        【解决方案4】:

        前面的回答者都有部分解决方案:您应该将updateF() 结合使用:

        Model.objects.filter(id=id).update(field=F('field') +1))
        

        请注意,这是一个就地更新,根本不需要 SELECT。

        【讨论】:

          猜你喜欢
          • 2021-10-21
          • 1970-01-01
          • 2021-12-19
          • 2011-05-19
          • 2020-12-03
          • 1970-01-01
          • 2022-01-08
          • 1970-01-01
          相关资源
          最近更新 更多