Fix task/project deletion broken by lazy='raise' on cascade relationships
Adding lazy='raise' to relationships with cascade='all, delete-orphan' broke db.delete() — SQLAlchemy tried to lazy-load related objects for Python-side cascade but lazy='raise' blocked it with MissingGreenlet. Fix: Add passive_deletes=True to subtasks, comments, assignments, tasks, and members relationships. This tells SQLAlchemy to defer cascade to PostgreSQL's ondelete=CASCADE FK constraint instead of loading objects in Python. Both the FK and ORM cascade are now aligned. Also added onError handler to deleteTaskMutation so failures are visible via toast instead of failing silently. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bb4212d17f
commit
03d0742dc4
@ -23,6 +23,6 @@ class Project(Base):
|
||||
updated_at: Mapped[datetime] = mapped_column(default=func.now(), onupdate=func.now())
|
||||
|
||||
# Relationships — lazy="raise" to prevent N+1 (mirrors CalendarMember pattern)
|
||||
tasks: Mapped[List["ProjectTask"]] = relationship(back_populates="project", cascade="all, delete-orphan", lazy="raise")
|
||||
tasks: Mapped[List["ProjectTask"]] = relationship(back_populates="project", cascade="all, delete-orphan", passive_deletes=True, lazy="raise")
|
||||
todos: Mapped[List["Todo"]] = relationship(back_populates="project", lazy="raise")
|
||||
members: Mapped[List["ProjectMember"]] = relationship(back_populates="project", cascade="all, delete-orphan", lazy="raise")
|
||||
members: Mapped[List["ProjectMember"]] = relationship(back_populates="project", cascade="all, delete-orphan", passive_deletes=True, lazy="raise")
|
||||
|
||||
@ -36,15 +36,18 @@ class ProjectTask(Base):
|
||||
subtasks: Mapped[List["ProjectTask"]] = sa_relationship(
|
||||
back_populates="parent_task",
|
||||
cascade="all, delete-orphan",
|
||||
passive_deletes=True,
|
||||
lazy="raise",
|
||||
)
|
||||
comments: Mapped[List["TaskComment"]] = sa_relationship(
|
||||
back_populates="task",
|
||||
cascade="all, delete-orphan",
|
||||
passive_deletes=True,
|
||||
lazy="raise",
|
||||
)
|
||||
assignments: Mapped[List["ProjectTaskAssignment"]] = sa_relationship(
|
||||
back_populates="task",
|
||||
cascade="all, delete-orphan",
|
||||
passive_deletes=True,
|
||||
lazy="raise",
|
||||
)
|
||||
|
||||
@ -201,6 +201,9 @@ export default function ProjectDetail() {
|
||||
toast.success('Task deleted');
|
||||
setSelectedTaskId(null);
|
||||
},
|
||||
onError: () => {
|
||||
toast.error('Failed to delete task');
|
||||
},
|
||||
});
|
||||
|
||||
const deleteProjectMutation = useMutation({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user