Python. Оптимизация функции записи\удаления данных в таблицу БД Posgresql (синхронизация)
Написал функцию "синхронизации" данных. Можно ли это реализовать одним запросом или оптимизировать решение? Какие могут возникнуть проблемы при использовании моего решения?
Сама задача выглядит так:
Есть база данных Postgres с таблицей local_data в которой есть поля: pkid, name, description
Eжедневно в эту таблицу необходимо заносить\удалять значения из сторонней БД которые прилетают в виде списка списков:
Например:
datalist = [['22ee-a0c529e9', 's-xxx-x-xxx01.example.com', 's-xxx-x-xxx01'],
['be47-771db3a9', 's-xxx-x-xxx02.example.com', 's-xxx-x-xxx02'],
...
['0a50-14acfca9', 's-xxx-x-xxxxx.example.com', 's-xxx-x-xxxxx']]
Свое решение вижу таким: делаю 2 проверки:
1. Если local_data есть строка которой нет в списке, это строку надо удалить из таблицы local_data - сравнение по всей строке позволит перезаписать строку (обновить) если изменились только поля name или description при совпадающих pkid
2. Если в переданном списке есть строка которая есть в local_data эту строку удаляем из списка datalist, проверяем что в datalist остались строки - пишем эти остатки в таблицу:
Функции чтения и записи данных:
def db_reader(table_name):
try:
cursor.execute("""SELECT FROM \"{}\"""".format(table_name))
table_data = cursor.fetchall()
if not table_data:
return None
else:
return table_data
except:
return False
def db_writer(datalist):
# Запрос и обработка текущей информации из локальной таблицы Postgresql DB
current_datalist = db_reader(local_data)
if current_datalist is None:
# Если таблица пустая
query = "INSERT INTO local_data (pkid, name, description) values %s"
psycopg2.extras.execute_values(cursor, query, datalist, template=None, page_size=1000)
cursor.close()
conn.close()
return True
elif current_datalist is not None:
# Удаление строк если они не найдены в переданном списке datalist
for row in current_datalist:
if row not in datalist:
cursor.execute("DELETE FROM local_data WHERE pkid = %s", (row[0],))
# Удаление из datalist строк присутсвующих в таблице local_data
for row in datalist.copy():
if row in current_datalist:
datalist.remove(row)
# Проверка что список для записи не пустой
if datalist:
query = "INSERT INTO local_data (pkid, name, description) values %s"
psycopg2.extras.execute_values(cursor, query, datalist, template=None, page_size=1000)
cursor.close()
conn.close()
return True
else:
# Не прочитали данные из local_data
return False