Как сделать update таблицы в БД массивом?
Подскажите пожалуйста, как можно сделать update таблицы используя массивы pd.DataFrame?
Сохранился фрагмент старой функции которая сравнивала значения таблицы из БД и таблицы которая приходит по API:
with self.connection.cursor() as cursor:
# Values - значения датафрейма полученные по API.
for i in values:
cursor.execute(f"""SELECT *
FROM {schema}.{tname}
WHERE article='{i[1]}';""")
row = cursor.fetchall()
# Проверка на идентичность. Проверялись только необходимые столбцы.
if not functools.reduce(lambda x, y: x and y,
map(lambda p, q: p == q,
(row[0][:3] + row[0][4:]),
tuple(i[:3]) + tuple(i[4:])), True):
# Если имелись расхождения, то циклом проверялось идентичность каждой ячейки и если значение отличалось, заменялось.
for cell, new_cell, column_name in \
zip(row[0][:3] + row[0][4:], tuple(i[:3]) + tuple(i[4:]),
tuple(column_name_list[:3] + column_name_list[4:])):
if cell != new_cell:
cursor.execute(f"""UPDATE {schema}.{tname}
SET {column_name[0]}='{new_cell}'
WHERE article='{i[1]}'""")
Такой способ обновления данных крайне неэффективен, особенно когда дело доходит до таблиц с большим количеством записей. Помимо этого нужно подобную логику адаптировать под каждую таблицу, что я считаю некорректно, наверняка можно сделать унифицировано.
Сейчас я пытаюсь реализовать следующую функцию:
def update_table(self, dataframe: pd.DataFrame, dataframe_db: pd.DataFrame, tname: str, schema: str = None, pk: list or str = "*"):
dataframe_comp = dataframe.compare(dataframe_db)
# UPDATE ACTION HERE
Но в голову приходит только пройти циклом по датафрейму сравнения, что в целом, то же самое что было ранее, но уже можно использовать для разных таблиц. Подскажите пожалуйста, какие есть инструменты в psycopg2, SQLAlchemy которые смогут обновить данные, возможно без цикла, либо, если циклом, то сделали бы это более эффективно.