Python psycopg2 вставка и обновление при конфликте - установите данные для существующего идентификатора и на основе условия - PullRequest
1 голос
/ 29 марта 2020

У меня есть таблица со столбцами, как показано ниже: (id, col1, col2, col3, col4). Мне нужно вставить новую строку в эту таблицу, с заданными данными, например, dict: data = {'id': 1, 'col1': 1, 'col2':1, 'col3':1, 'col4': 1}.

Я хочу использовать приведенный ниже запрос для вставки данных в таблицу, если идентификатор не существует, или для обновления таблицы если идентификатор существует:

query = 
'''
    INSERT INTO tablename (id, col1, col2, col3, col4)
    VALUES (%(id)s, %(col1)s, %(col2)s, %(col3)s, %(col4)s)
    ON CONFLICT (id) DO UPDATE SET
    col2 = col2 + 1;
'''
result = cur.execute(query, data)

Я могу передать данные в блок вставки, но с помощью блока «Конфликт», когда выполняется обновление, col2 = col2 + data ['col2] выдает ошибку как column referance "col2" is ambiguous ,

Другой вопрос - как обновить значение col2 на основе условия из других столбцов, например: col2 = col2 + 1 if col1 == data['col1] else col2 = col2

1 Ответ

1 голос
/ 30 марта 2020

Рассмотрите возможность повторного использования элементов словаря в качестве дополнительного параметра и используйте имя таблицы в качестве псевдонима:

query = '''INSERT INTO tablename (id, col1, col2, col3, col4)
           VALUES (%(id)s, %(col1)s, %(col2)s, %(col3)s, %(col4)s)
           ON CONFLICT (id) DO 
           UPDATE SET col2 = tablename.col2 + %(col2)s;
        '''

result = cur.execute(query, data)

На самом деле, вы можете использовать excluded псевдоним:

...
UPDATE SET col2 = tablename.col2 + excluded.col2;

И для условного логика c используйте оператор CASE:

query = '''INSERT INTO tablename (id, col1, col2, col3, col4)
           VALUES (%(id)s, %(col1)s, %(col2)s, %(col3)s, %(col4)s)
           ON CONFLICT (id) DO 
           UPDATE SET col2 = CASE 
                                 WHEN tablename.col1 = %(col1)s
                                 THEN tablename.col2 + 1
                                 ELSE tablename.col2
                             END;
        '''

result = cur.execute(query, data)

И снова вы можете использовать псевдоним excluded:

...
CASE 
   WHEN tablename.col1 = excluded.col1
   THEN tablename.col2 + 1 
   ELSE tablename.col2 
END;
...