Как исключить дубликаты записей при добавлении CSV файла в таблицу БД

Таблица выглядит таким образом:

Категория по буквам |Категория по аббревиатуре|Дата      |П_1     |П_2
____________________|_________________________|__________|________|________|
      Буквенная     |ZZZ                      |07.20.2020|2       |3
      ______________|_________________________|__________|________|________|
      Численная     |ZZZ                      |07.20.2020|1       |1
      ______________|_________________________|__________|________|________|
      Численная     |AAA                      |07.20.2020|3       |7
      ______________|_________________________|__________|________|_________
      Буквенная     |CCC                      |07.20.2020|40      |1
      ______________|_________________________|__________|________|_________
      Буквенная     |CCC                      |07.24.2020|0       |0

Нужно чтобы блок данных загружался в таблицу БД после проверки, что еще нет данных за сформированную дату (дубликаты данных), иначе выводится уведомление, что данные с такой датой уже существуют в БД.

Данные загружаются таким образом:

import urllib
from sqlalchemy import create_engine
import pyodbc
params = urllib.parse.quote_plus("DRIVER={SQL Server Native Client 11.0};SERVER=dagger;DATABASE=test;UID=user;PWD=password")

engine = create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)
df.to_sql("mytable", engine, index=False, if_exists="append")

Ответы (1 шт):

Автор решения: MaxU

Я вижу два варианта решения:

  1. заливать данные из DataFrame во временную таблицу и потом делать вставку с проверкой на стороне SQL Server.
  2. вычитываем всю таблицу из SQL Server в DataFrame, получаем новый DataFrame с записями, которые отстутствуют в таблице SQL Server, заливаем данные обратно в таблицу.

Второй подход может быть очень медленным и со временем таблица может стать настолько большой, что она не поместится в памяти в виде DataFrame. Поэтому я бы выбрал первый вариант.

Решение:

import urllib
params = urllib.parse.quote_plus("DRIVER={SQL Server Native Client 11.0};SERVER=dagger;DATABASE=test;UID=user;PWD=password")

engine = create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)
# вставляем данные во временную таблицу
df.to_sql("tmp_table", index=False, if_exists="replace")
# подготавливаем SQL для вставки уникальных записей
qry = """
INSERT INTO target_table (col1, col2, col3)
SELECT * FROM tmp_table tmp
WHERE NOT EXISTS (
    SELECT 1 
    FROM target_table tgt 
    WHERE tgt.col1 = tmp.col1 AND tgt.col2 = tmp.col2 ...
)
"""
con = engine.connect()
cur = con.cursor()
cur.execute(qry)
con.commit()
→ Ссылка