refactor: notes-python — описательные имена файлов/ресурсов + комментарии
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 файлы
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
# 2026-03-09
|
||||
# handler.py — возвращает все записи из таблицы notes.
|
||||
# GET/POST /fn/default/notes-list → JSON массив записей, сортировка по created_at DESC.
|
||||
import os
|
||||
import psycopg2
|
||||
import psycopg2.extras
|
||||
|
||||
|
||||
def handle(event):
|
||||
dsn = os.environ['PG_DSN']
|
||||
conn = psycopg2.connect(dsn)
|
||||
try:
|
||||
cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
||||
cur.execute(
|
||||
"SELECT id, title, body, created_at::text FROM notes ORDER BY created_at DESC"
|
||||
)
|
||||
rows = cur.fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
except Exception as e:
|
||||
return {'error': str(e)}
|
||||
finally:
|
||||
conn.close()
|
||||
@@ -0,0 +1,31 @@
|
||||
# 2026-03-09
|
||||
# notes_list.py — чтение всех записей из таблицы notes.
|
||||
#
|
||||
# Назначение: отдать полный список заметок одним запросом.
|
||||
# Принимает GET или POST — тело/query параметры игнорируются.
|
||||
# Возвращает JSON-массив, сортировка: новые записи первые (ORDER BY created_at DESC).
|
||||
#
|
||||
# Пример ответа:
|
||||
# [
|
||||
# {"id": 3, "title": "Hello", "body": "World", "created_at": "2026-03-09 ..."},
|
||||
# {"id": 1, "title": "First", "body": "Note", "created_at": "2026-03-08 ..."}
|
||||
# ]
|
||||
import os
|
||||
import psycopg2
|
||||
import psycopg2.extras
|
||||
|
||||
|
||||
def handle(event):
|
||||
dsn = os.environ['PG_DSN']
|
||||
conn = psycopg2.connect(dsn)
|
||||
try:
|
||||
cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
||||
cur.execute(
|
||||
"SELECT id, title, body, created_at::text FROM notes ORDER BY created_at DESC"
|
||||
)
|
||||
rows = cur.fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
except Exception as e:
|
||||
return {'error': str(e)}
|
||||
finally:
|
||||
conn.close()
|
||||
+13
-6
@@ -1,10 +1,17 @@
|
||||
# 2026-03-09
|
||||
# handler.py — CRUD роутер для таблицы notes.
|
||||
# Роутинг по event._path (sub-path URL):
|
||||
# POST /fn/default/notes/add?title=...&body=... → INSERT
|
||||
# POST /fn/default/notes/update?id=1&title=... → UPDATE
|
||||
# POST /fn/default/notes/delete?id=1 → DELETE
|
||||
# _path и _query добавляет runtime из HTTP запроса (server.py).
|
||||
# notes_crud.py — CRUD роутер для таблицы notes.
|
||||
#
|
||||
# Назначение: единая функция, которая обрабатывает все операции с записями.
|
||||
# Роутинг осуществляется по sub-path URL (event._path), который runtime
|
||||
# берёт из входящего HTTP-запроса и добавляет в event автоматически.
|
||||
#
|
||||
# Доступные маршруты (все POST):
|
||||
# /fn/default/notes/add?title=...&body=... → создать запись
|
||||
# /fn/default/notes/update?id=1&title=...&body=... → обновить запись
|
||||
# /fn/default/notes/delete?id=1 → удалить запись
|
||||
#
|
||||
# Параметры берутся из query string (event._query) или из тела запроса (event).
|
||||
# event._path и event._query добавляет Python runtime (server.py) автоматически.
|
||||
import os
|
||||
import psycopg2
|
||||
import psycopg2.extras
|
||||
@@ -1,26 +0,0 @@
|
||||
# 2026-03-09
|
||||
# handler.py — универсальный исполнитель SQL запросов.
|
||||
# Принимает event.statements — массив SQL строк, выполняет последовательно.
|
||||
# Используется sless_job для DDL операций (CREATE TABLE, миграции и т.д.)
|
||||
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()
|
||||
@@ -0,0 +1,39 @@
|
||||
# 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()
|
||||
Reference in New Issue
Block a user