Как обрабатывать нарушения ограничений первичного ключа с помощью pyodbc executemany()

У меня есть скрипт для вставки DataFrame в таблицу с помощью executemany().

Проблема в том, что эта таблица имеет идентификатор Первичный ключ, и иногда может возникнуть необходимость вставить строку с таким же идентификатором.

Я хотел бы знать, есть ли простой способ обработать такое исключение и продолжить выполнение executemany().

Альтернативой, о которой я думал, является проверка всех Я БЫ DataFrame, которые находятся в таблице, и удаление их перед вставкой в ​​базу данных... но я не знаю, будет ли это эффективным...

Мой код:

params = (tuple(row) for _, row in df.iterrows())
sql = '''INSERT INTO stilingue.stalker_comments values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'''
start = time.time()
try:
    self.cursor.executemany(sql, params)
    self.conn.commit()
except Exception as e:
    print(e)
    self.conn.rollback()
    print('Something went wrong...')
end = time.time()
print('Execution time: {0:.2f} seconds.'.format(end-start))

фрейм данных:

    channel followers   gender  hashtags    interactions    likes   location    mentions    name    page_comment    ... text    themes  uid user_image_url  user_url    username    verified    videoplays  business    rt_count
0   Inbox do Facebook   0   Não Definido        0   0           Midiam Mendes   False   ... Sacanagem isso né?? Poorq vocês dizeram que o ...       1995608377159933    https://storage.googleapis.com/usersstilingue/...           False   0   Itaú    0
1   Inbox do Facebook   0   Não Definido        0   0           Midiam Mendes   False   ... Eu tenho provas , e posso processar vocês!!     1995608377159933    https://storage.googleapis.com/usersstilingue/...           False   0   Itaú    0
2   Inbox do Facebook   0   Não Definido        0   0           Midiam Mendes   False   ... Isso é um absurdo       1995608377159933    https://storage.googleapis.com/usersstilingue/...           False   0   Itaú    0

Проследить:

('23000', "[23000] [Microsoft][ODBC SQL Server Driver][SQL Server]Violation of PRIMARY KEY constraint 'PK__stalker___DD37D91A4691B0F7'. Cannot insert duplicate key in object 'stilingue.stalker_comments'. The duplicate key value is (m__g64-pbys7OlEvp8xmfyktlNIHrUPQPiNrcKrPVOF_Lj84OJfN4WtAJ92lj7YnzAOQ1B7EDCJf85k_UcwB0-4Q). (2627) (SQLExecDirectW); [23000] [Microsoft][ODBC SQL Server Driver][SQL Server]The statement has been terminated. (3621)")

Одной из альтернатив может быть использование df.to_sql для загрузки строк во временную таблицу, а затем использование инструкции SQL MERGE для вставки строк в основную таблицу.

Gord Thompson 22.01.2019 13:55

покажи нам трассировку и фрейм данных

Steven G 22.01.2019 13:58

@StevenG я отредактировал пост. @ Горд Томпсон, как вы думаете, df.to_sql быстрее, чем executemany (), даже с fast_executemany = True?

Lucas Hort 22.01.2019 15:57
to_sql может использовать преимущества fast_executemany; подробности здесь.
Gord Thompson 22.01.2019 17:39

@GordThompson Спасибо!

Lucas Hort 23.01.2019 13:20
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
5
1 172
1

Ответы 1

Если ваши данные невелики, самый простой способ — создать в базе данных временную таблицу, не имеющую PK. Затем вставьте данные в этот временный файл, удалите дублирование из временного (если у вас есть база данных SQL-сервера, вы можете использовать следующий синтаксис для удаления дублирования) и вставьте свои данные в основную таблицу.

 WITH table_1 AS 
(SELECT *,RN=ROW_NUMBER() OVER(PARTITION BY [pk_field]
 order by date) 
 FROM [temporary_table])
 DELETE FROM table_1  WHERE RN>1

Другие вопросы по теме