Python файлы: - handler.py → sql_runner.py (entrypoint: sql_runner.handle) - handler.py → notes_crud.py (entrypoint: notes_crud.handle) - handler.py → notes_list.py (entrypoint: notes_list.handle) TF ресурсы переименованы: - sless_function.notes → sless_function.notes_crud - sless_trigger.notes_http → sless_trigger.notes_crud_http - sless_job.create_table → sless_job.notes_table_init - sless_job.create_index → sless_job.notes_index_init - archive_file.notes → archive_file.notes_crud_zip - archive_file.sql_runner → archive_file.sql_runner_zip - archive_file.notes_list → archive_file.notes_list_zip Добавлены подробные комментарии во все .tf файлы
40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
# 2026-03-09
|
||
# sql_runner.py — универсальный DDL/SQL исполнитель.
|
||
#
|
||
# Назначение: выполнять произвольные SQL запросы переданные через event.
|
||
# Используется ТОЛЬКО через sless_job (init.tf) — HTTP-триггера нет намеренно,
|
||
# чтобы никто снаружи не мог выполнить произвольный SQL.
|
||
#
|
||
# Входящий event:
|
||
# {
|
||
# "statements": [
|
||
# "CREATE TABLE IF NOT EXISTS ...",
|
||
# "CREATE INDEX IF NOT EXISTS ..."
|
||
# ]
|
||
# }
|
||
#
|
||
# Все statements выполняются последовательно в одной транзакции.
|
||
# Если хотя бы один упал — транзакция откатывается целиком.
|
||
import os
|
||
import psycopg2
|
||
|
||
|
||
def handle(event):
|
||
dsn = os.environ['PG_DSN']
|
||
statements = event.get('statements', [])
|
||
if not statements:
|
||
return {'error': 'no statements provided'}
|
||
|
||
conn = psycopg2.connect(dsn)
|
||
try:
|
||
cur = conn.cursor()
|
||
for sql in statements:
|
||
cur.execute(sql)
|
||
conn.commit()
|
||
return {'ok': True, 'executed': len(statements)}
|
||
except Exception as e:
|
||
conn.rollback()
|
||
return {'error': str(e)}
|
||
finally:
|
||
conn.close()
|