Найти в Дзене

UPSERT в БД Oracle (Python, SQLAlchemy)

Всем привет. Я дата-инженер и достаточно долгое время работал с БД PostgreSQL. Сменив работу я столкнулся с Oracle и его особенностями. Например, с отсутствием такой удобной конструкции при записи данных, как INSERT... ON CONFLICT DO UPDATE. Есть ее аналог, но чтобы понять объяснение из документации, нужно напрягать мозг. Напишу в том виде, в котором это было бы понятно мне, когда я впервые это увидел. Может, пригодится еще кому-то. Для записи я использую Python и SQLAlchemy, но программного кода здесь не будет, только SQL в нужном формате. Итак, вместо "INSERT … ON CONFLICT DO... "в Oracle используется MERGE. Сам запрос будет выглядеть так: MERGE INTO целевая_таблица USING DUAL ON (col_1 = :col_1, col_2 = :col_2) WHEN MATCHED THEN UPDATE SET col_3 = :col_3, col_4 = :col_4 WHEN NOT MATCHED THEN INSERT (col_1, col_2, col_3, col_4) VALUES (:col_1, :col_2, :col_3, :col_4) Теперь немного объяснений: DUAL - это аналог excluded из Postgres. В DUAL ON () мы указываем условие сравнения. Это

Всем привет. Я дата-инженер и достаточно долгое время работал с БД PostgreSQL. Сменив работу я столкнулся с Oracle и его особенностями. Например, с отсутствием такой удобной конструкции при записи данных, как INSERT... ON CONFLICT DO UPDATE. Есть ее аналог, но чтобы понять объяснение из документации, нужно напрягать мозг. Напишу в том виде, в котором это было бы понятно мне, когда я впервые это увидел. Может, пригодится еще кому-то.

Для записи я использую Python и SQLAlchemy, но программного кода здесь не будет, только SQL в нужном формате.

Итак, вместо "INSERT … ON CONFLICT DO... "в Oracle используется MERGE.

Сам запрос будет выглядеть так:

MERGE INTO целевая_таблица USING DUAL ON (col_1 = :col_1, col_2 = :col_2)
WHEN MATCHED THEN UPDATE SET col_3 = :col_3, col_4 = :col_4
WHEN NOT MATCHED THEN INSERT (col_1, col_2, col_3, col_4)
VALUES (:col_1, :col_2, :col_3, :col_4)

Теперь немного объяснений:

DUAL - это аналог excluded из Postgres.

В DUAL ON () мы указываем условие сравнения. Это не обязательно должен быть первичный ключ, набор колонок может быть любым. Например при указании DUAL ON (column = 2) Oracle будет искать колонку с этим значением. Дальше, в зависимости от того, есть ли запись с этим значением колонки, будет выполнено действие в WHEN MATCHED или в WHEN NOT MATCHED. Соответственно, если запись есть, прописываем, что обновить. Если нет - что записать.