【问题标题】:postgres skip row if Foreign Key is referenced如果引用了外键,则 postgres 跳过行
【发布时间】:2021-05-09 13:03:49
【问题描述】:

我正在尝试从表“users”中删除行列表,一些 user_ids 在 user_plan 表中被引用为 FK。我想在“for循环”中跳过删除,即处理错误

x= [1,31,32,33,34]
for i in x:
    cursor.execute("DELETE FROM users WHERE id=%s", (str(i),))

>>>psycopg2.errors.ForeignKeyViolation: update or delete on table "user_plan" violates foreign key constraint "user_fk_id" on table "user_plan"
DETAIL:  Key (id)=(1) is still referenced from table "user_plan".

如何修改查询,以便在其他地方使用 FK 时跳过删除?

【问题讨论】:

    标签: python postgresql psycopg2


    【解决方案1】:
    WHERE id IN (1,31,32,33,34)
    

    你可以简单地做到这一点:

    values = ",".join(x)
    cursor.execute("DELETE FROM users WHERE id=%s", (values,))
    

    我在PHP中使用它,在python中尝试一下,它应该是单词。

    【讨论】:

    • 错误是什么??另一个问题:您想删除x 列表中的内容还是跳过?
    • 你也是怎么得到 x 值的?
    • 不,如果它在另一个表中使用,则直接跳过它
    • 是的,我的意思是从另一个表中,您可以使用join 加入第二个表,如果条件简单,只需反转它就很容易
    【解决方案2】:

    我不确定如何转换为您的混淆层 (psycopg2),但使用直接 SQL,您可以将谓词“and not exists (select ...) 添加到 where 子句。请参阅demo.

    delete 
      from users u 
     where u.user_id = any('{1,31,32,33,34}')
       and not exists ( select null 
                           from user_plan up 
                          where up.user_id = u.user_id
                       );
    

    以上是基于“FK 用于其他地方”的假设,您具体指的是表 user_plan。如果还有其他表对用户具有 FK,那么您需要为每个表包含一个 *not exists * 谓词。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-08
      相关资源
      最近更新 更多