Обновление таблицы без использования SQL_SAFE_UPDATES - PullRequest
1 голос
/ 29 мая 2020

Я пытаюсь обновить некоторые записи с помощью этого запроса, который, по сути, является просто способом установить «состояние» для клиента с учетом его «дней с момента последнего заказа»:

        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;

Но я ' m получение:

Код ошибки: 1175. Вы используете режим безопасного обновления и пытались обновить таблицу без WHERE, в которой используется столбец KEY. Чтобы отключить безопасный режим, переключите параметр в настройках -> SQL Редактор и переподключение.

Я использую ключ таблицы в финальном WHERE, c1.id - это ключ таблицы customers. Использование SET SQL_SAFE_UPDATES = 0; не вариант. Я также пробовал использовать WHERE c1.id > 0, но безрезультатно.

Обратите внимание, что я попытался запустить запрос вручную, изменив SET SQL_SAFE_UPDATES = 0;, запрос работает, как ожидалось, но это должен быть автоматический c процесс.

Итак, мои варианты:

  1. Используя один запрос, SQL_SAFE_UPDATES нельзя использовать.
  2. Используя Python курсоры, SQL_SAFE_UPDATES можно использоваться. (см. БОКОВОЕ ПРИМЕЧАНИЕ )
  3. [вставьте здесь параметр]
  4. (я не хочу этого делать) Итерировать по каждой записи (используя Python ORM ) и обновите запись. Это глупо и займет вечность.

ОБНОВЛЕНИЕ

Также пробовали:

  • Использование того же идентификатора

    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;
    
  • Комбинация обоих идентификаторов:

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

Ни один из них не работает. По-прежнему получаю Error Code: 1175.

СТОРОННЕЕ ПРИМЕЧАНИЕ

Это часть процесса Python / Flask с использованием клиента MySQL python и курсоров. Я могу использовать 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
    ''')
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...