zoukankan      html  css  js  c++  java
  • django.db.utils.OperationalError: (1093, "You can't specify target table 'xxx' for update in FROM clause")

    这个错误的意思是,不能在update某张表的where条件中,再次select这张表的某些值作为筛选条件,比如:

    update message set content = "hello" where id in (select min(id) from message group by uid)
    

    修改sql语句的解决方法是:

    通过 select * from message 创建一个message的临时表,这样,update与select min(id) from操作的就不是同一张实体表了

    update message set content = "hello" where id in (select min(id) from (select * from message) group by uid)
    

    为什么在Django中会遇到这个问题呢?因为objects.values_list('id', flat=True)容易让人误以为返回的是一个list,实际上返回的是一个ValuesListQuerySet。例如:

    uids = User.objects.filter(first_name="Ben").values_list('id', flat=True)
    query = Message.objects.filter(uid__in=uids).update(content="hello")
    print(query.query)
    

    uids变量并没有存取出的用户id,甚至这个query都没有执行,一切要等到uid__in=uids这里,uids所代表的query才会和update Message的query合成一个sql语句去执行

    但是uids这个变量命名特别容易让人误解这是一个list,然后如果在后面一不小心在User的过滤条件中用到了这个变量,比如

    User.objects.filter(id__in=uids).update(name="Tex")
    

    就会出现上述的问题

    实际上,将uids转为list就可以解决这个问题。但是规范变量名是此类query问题的根源解决方法

    uids = list(User.objects.filter(first_name="Ben").values_list('id', flat=True))
    uids_query = User.objects.filter(first_name="Ben").values_list('id', flat=True)
    
  • 相关阅读:
    SpringSecurity配置
    SpringBoot整合Mybatis
    springboot整合JDBC
    SpringBoot的WEB流程
    List&TreeSet实现斗地主发牌及牌序
    SpringBoot第一个程序
    项目错误总结2021.4.21
    Spring整合Mybatis
    学习——构建民航业知识图谱并实现语义查询的
    新闻文本分类——词云可视化
  • 原文地址:https://www.cnblogs.com/luozx207/p/11857898.html
Copyright © 2011-2022 走看看