PostgreSQL OLD не работает в триггере уровня оператора после обновления
Работает, если я выбираю конкретный ID следующим образом:
BEGIN
UPDATE course
SET points = (SELECT COALESCE(SUM("lesson"."points"), 0) AS "sum_points" FROM "course" LEFT OUTER JOIN "lesson" ON ("course"."id" = "lesson"."course_id") WHERE "course"."id" = 7)
WHERE "course"."id" = 7;
RETURN NULL;
END;
Но не работает с OLD, который является обновляемым экземпляром.
BEGIN
UPDATE course
SET points = (SELECT COALESCE(SUM("lesson"."points"), 0) AS "sum_points" FROM "course" LEFT OUTER JOIN "lesson" ON ("course"."id" = "lesson"."course_id") WHERE "course"."id" = OLD."course_id")
WHERE "course"."id" = OLD."course_id";
RETURN NULL;
END;
Я использую django-pgtriggers
OLD и NEW всегда NULL в случае Statement level.

Замените level=pgtrigger.Statement на level=pgtrigger.Row
@pgtrigger.register(
pgtrigger.Trigger(
name="add_course_point",
level=pgtrigger.Row,
when=pgtrigger.After,
operation=pgtrigger.Update,
func=f"""
UPDATE course
SET points = (SELECT COALESCE(SUM("lesson"."points"), 0) AS "sum_points" FROM "course" LEFT OUTER JOIN "lesson" ON ("course"."id" = "lesson"."course_id") WHERE "course"."id" = OLD."course_id")
WHERE "course"."id" = OLD."course_id";
RETURN NULL;
"""
)
)
или добавьте referencing=pgtrigger.Referencing(old='old_table_name') и затем измените свою функцию.
Я зарегистрировал 2 триггера. Первый - перед обновлением триггер для вставленных уроков. Второй - после обновления триггер для обновленных и удаленных уроков. Очки курса увеличиваются или уменьшаются на сумму его очков уроков в конце концов.
@pgtrigger.register(
pgtrigger.Trigger(
name="add_course_point",
operation=pgtrigger.Insert,
level=pgtrigger.Row,
when=pgtrigger.Before,
func=f"""
UPDATE course
SET points = (points + NEW.points)
WHERE "course"."id" = NEW.course_id;
RETURN NEW;
""",
),
pgtrigger.Trigger(
name="update_course_point",
operation=(pgtrigger.Update | pgtrigger.Delete),
level=pgtrigger.Row,
when=pgtrigger.After,
func=f"""
UPDATE course
SET points = (SELECT COALESCE(SUM("lesson"."points"), 0) AS "sum_points" FROM "course" LEFT OUTER JOIN "lesson" ON ("course"."id" = "lesson"."course_id") WHERE "course"."id" = OLD.course_id)
WHERE "course"."id" = OLD.course_id;
RETURN NULL;
""",
),
)

