PostgreSQL добавление значения в дочернюю таблицу
Создаётся платеж, записывается в таблицы: платежи (payments
) и история изменения статусов (payments_approval_history
). В таблице истории изменений есть внешний ключ из ссылающийся на таблицу договоров.
Правильно ли производить запись в таблицу payments
, делать commit
, а после делать запись в таблицу payments_approval_history
и тоже делать commit
?
Как защититься от случая, когда мы записали в данные в одну таблицу, но получили ошибку при записи во вторую, и в итоге потеряли запись, ну и не поняли, что потеряли эту запись?
DROP TABLE IF EXISTS payments;
DROP TABLE IF EXISTS payments_approval_history;
CREATE TABLE payments(
payment_id INT GENERATED ALWAYS AS IDENTITY,
payment_number VARCHAR(255) NOT NULL,
PRIMARY KEY(payment_id)
);
CREATE TABLE payments_approval_history(
confirm_id INT GENERATED ALWAYS AS IDENTITY,
payment_id INT,
status_id INT DEFAULT 1
PRIMARY KEY(confirm_id),
CONSTRAINT fk_payment
FOREIGN KEY(payment_id)
REFERENCES payments(payment_id)
);
Записываем данные в таблицы. (упрощенный код)
import psycopg2 as pg
from psycopg2.extras import execute_values
values_p = [
('num-1'),
('num-2'),
('num-3')
]
with pg.connect('<connection string>') as conn:
with conn.cursor() as cur:
try:
p_id = execute_values(
cur,
"""
INSERT INTO payments (
payment_number
)
VALUES %s on conflict do nothing
RETURNING payment_id;
""",
values_p,
template="""(%s)""",
page_size=len(values_p),
fetch=True
)
except Exception:
conn.rollback()
raise
else:
conn.commit()
values_p_a_h = []
[values_p_a_h.append((x,)) for x in p_id]
try:
execute_values(
cur,
"""
INSERT INTO payments_approval_history (
payment_id
)
VALUES %s on conflict do nothing;
""",
values_p_a_h,
template="""(%s::int)""",
page_size=len(values_p_a_h) # вот тут возможны варианты. По умолчанию 500
)
except Exception:
conn.rollback()
raise
else:
conn.commit()
Вопрос, правильно ли так делать? если нет, то как сделать лучше?