Postgres Версия: 11
Код процедуры:
CREATE OR REPLACE PROCEDURE public.prc_insert_proc(table_name character varying)
LANGUAGE plpgsql
AS $procedure$ declare StartTime timestamptz;
EndTime timestamptz;
Delta double precision;
err_context text;
tab_partition RECORD;
v_tab_partition varchar;
begin
for tab_partition in (SELECT
child.relname AS child
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
JOIN pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace
JOIN pg_namespace nmsp_child ON nmsp_child.oid = child.relnamespace
WHERE parent.relname=table_name) loop
v_tab_partition = tab_partition.child;
begin
execute 'insert
into
test_tab (id,
report_date,
effective_asof_date,
effective_until_date,
active_flag) select id,
to_date(report_date,''YYMMDD'') report_date,
now(),
''31-Dec-2200'',
''Y''
from '||
tab_partition.child ||' on
conflict (id) do update set report_date=excluded.report_date;';
commit;
end;
end loop;
exception
when others then
GET STACKED DIAGNOSTICS err_context = PG_EXCEPTION_CONTEXT;
RAISE INFO 'Error Name:%',SQLERRM;
RAISE INFO 'Error State:%', SQLSTATE;
RAISE INFO 'Error Context:%', err_context;
end;
$procedure$;
Я вызываю вышеуказанную процедуру, создав механизм sqlalchemy и затем вызвав эту процедуру.
def load_test(session, table, log): # pragma: no cover
try:
sql = "call prc_insert_proc('" + \
table + "');"
session.execute(text(sql).execution_options(autocommit=False))
session.commit()
except ErrorBase as e:
log.error(f"{str(e)}")
raise
Itподбрасывает следующую ошибку.Сессия была создана с использованием sessionmaker и create_engine.
engine = create_engine(config.connection_string, echo=False)
Session = sessionmaker()
Session.configure(bind=engine)
session = Session()
недопустимое завершение транзакции
Я довольно новичок как в sqlalchemy, так и в PostgreSQL. Каждый раздел таблицы имеет околомиллион записей и я хочу сделать коммит после каждой вставки.Другой вариант - получить список разделов в скрипте python и добавить параметр имени раздела в процедуру.Выполните цикл по процедуре в python и фиксируйте после каждого вызова.Однако, когда я прочитал это в PostgreSQL 11, мы можем зафиксировать внутри процедуры, чем я думал об этом.