在不使用SQL_SAFE_UPDATES的情况下更新表

时间:2020-05-29 18:29:37

标签: python mysql sql database

我正在尝试使用此查询更新一些记录,这基本上只是考虑到客户“自上次下单以来的天数”为客户设置“状态”的一种方式:

        UPDATE customers AS c1
        INNER JOIN (
          SELECT id, DATEDIFF(NOW(), agg.cdt) AS acdt
          FROM customers
          INNER JOIN
            (
              SELECT c.id AS cid, max(o.datetime) as cdt
              FROM customers AS c
              LEFT JOIN orders o ON o.customer_id = c.id
              WHERE o.state = 20
              GROUP BY c.id
            ) AS agg ON customers.id = agg.cid
          WHERE account_type IN (1, 2)
            AND deleted = 0
            AND (account_management_state IN (0, 1, 2) OR account_management_state IS NULL)
        ) AS c2 ON c1.id = c2.id
        SET c1.account_management_state = CASE
          WHEN c2.acdt <= 90 THEN 0
          WHEN c2.acdt >= 91 AND c2.acdt <= 360 THEN 1
          WHEN c2.acdt > 360 OR c2.acdt IS NULL THEN 2
          END
        WHERE c1.id = c2.id;

但是我得到了:

错误代码:1175。您正在使用安全更新模式,并且尝试在不使用使用KEY列的WHERE的情况下更新表。要禁用安全模式,请在“首选项”->“ SQL编辑器”中切换选项,然后重新连接。

我在最后一个WHERE中使用了表键,c1.idcustomers的表键。不能使用SET SQL_SAFE_UPDATES = 0;。我也尝试使用WHERE c1.id > 0无济于事。

请注意,我尝试手动更改SET SQL_SAFE_UPDATES = 0;来运行查询,该查询按预期运行,但这应该是一个自动过程。

所以我的选择是:

  1. 使用单个查询,无法使用SQL_SAFE_UPDATES
  2. 使用Python游标,可以使用SQL_SAFE_UPDATES。 (请参见侧注
  3. [在此处插入选项]
  4. (我不想这样做)(使用Python ORM)遍历每个记录并更新记录。这是愚蠢的,将永远存在。

更新

也尝试过:

  • 使用相同的ID

    UPDATE
      ...
    WHERE c1.id = c1.id ;
    
  • 在每个子查询之后增加一个巨大的限制(@Akina建议):

    UPDATE customers AS c1
    INNER JOIN (
      SELECT id, DATEDIFF(NOW(), agg.cdt) AS acdt
      FROM customers
      INNER JOIN
        (
          SELECT c.id AS cid, max(o.datetime) as cdt
          FROM customers AS c
          LEFT JOIN orders o ON o.customer_id = c.id
          WHERE o.state = 20
          GROUP BY c.id
          LIMIT 100000000
        ) AS agg ON customers.id = agg.cid
      WHERE account_type IN (1, 2)
        AND deleted = 0
        AND (account_management_state IN (0, 1, 2) OR account_management_state IS NULL)
      LIMIT 100000000
    ) AS c2 ON c1.id = c2.id
    SET c1.account_management_state = CASE
      WHEN c2.acdt <= 90 THEN 0
      WHEN c2.acdt >= 91 AND c2.acdt <= 360 THEN 1
      WHEN c2.acdt > 360 OR c2.acdt IS NULL THEN 2
      END
    WHERE c1.id = c2.id;
    
  • 两个ID的组合:

    UPDATE
      ...
    WHERE c1.id > 0 and c2.id > 0;
    

他们都没有工作。仍然得到Error Code: 1175

旁注

这是使用MySQL python客户端和游标的Python / Flask进程的一部分。我可以使用SQL_SAFE_UPDATES,只要它是通过Python游标完成的。这不起作用:

  • 使用不同的查询(不会引发错误,它只会更新任何内容):

    connection = db.get_conn()
    cursor = connection.cursor()
    cursor.execute('SET SQL_SAFE_UPDATES = 0;')
    cursor.execute(query) # from the original query
    cursor.execute('SET SQL_SAFE_UPDATES = 1;')
    
  • 使用单个查询(不会引发错误,它只会更新任何内容):

    connection = db.get_conn()
    cursor = connection.cursor()
    cursor.execute('''
        SET SQL_SAFE_UPDATES = 0;
        UPDATE ...;
        SET SQL_SAFE_UPDATES = 1;
    ''')
    
  • 使用BEGIN .. END(以为我看到了光,但没有看到),得到ProgrammingError

    connection = db.get_conn()
    cursor = connection.cursor()
    cursor.execute('''
        BEGIN
            SET SQL_SAFE_UPDATES = 0;
            UPDATE ...;
            SET SQL_SAFE_UPDATES = 1;
        END
    ''')
    

1 个答案:

答案 0 :(得分:0)

我知道这已经很长时间了,但今天可能和你的和我的有同样的问题。 我已经通过在关闭连接之前提交更改来解决它 在关闭连接“cnx.commit()”之前添加这个 希望能帮到你