sless-primer/POSTGRES/code/pg-upsert/pg_upsert.py
2026-03-22 17:08:18 +04:00

37 lines
1.7 KiB
Python

# 2026-03-21 — pg-upsert: INSERT ... ON CONFLICT (title) DO UPDATE.
# Тестирует: идемпотентность вставки — один и тот же title можно вызывать 100 раз подряд.
# Требует уникального индекса на title — создаётся при первом вызове (CREATE UNIQUE INDEX IF NOT EXISTS).
import os, psycopg2
def upsert(event):
title = str(event.get("title", "upsert-default"))[:255]
payload = str(event.get("payload", ""))[:500]
conn = psycopg2.connect(
host=os.environ["PGHOST"], port=int(os.environ.get("PGPORT", 5432)),
dbname=os.environ["PGDATABASE"], user=os.environ["PGUSER"],
password=os.environ["PGPASSWORD"], sslmode=os.environ.get("PGSSLMODE", "require"),
)
try:
with conn.cursor() as cur:
# Создаём уникальный индекс если нет — для поддержки ON CONFLICT
cur.execute(
"CREATE UNIQUE INDEX IF NOT EXISTS terraform_demo_table_title_uniq "
"ON terraform_demo_table (title)"
)
cur.execute(
"INSERT INTO terraform_demo_table (title) VALUES (%s) "
"ON CONFLICT (title) DO UPDATE SET created_at = now() "
"RETURNING id, title, created_at::text, xmax",
(title,),
)
row = cur.fetchone()
was_insert = row[3] == 0 # xmax=0 означает INSERT, иначе UPDATE
conn.commit()
return {
"id": row[0], "title": row[1], "created_at": row[2],
"action": "inserted" if was_insert else "updated",
}
finally:
conn.close()