diff --git a/src/migrations/versions/2025_08_06_2341-197b195208e8_add_cascade_delete_to_tasks.py b/src/migrations/versions/2025_08_06_2341-197b195208e8_add_cascade_delete_to_tasks.py new file mode 100644 index 0000000..a64aa6b --- /dev/null +++ b/src/migrations/versions/2025_08_06_2341-197b195208e8_add_cascade_delete_to_tasks.py @@ -0,0 +1,65 @@ +"""add_cascade_delete_to_tasks + +Revision ID: 197b195208e8 +Revises: a2fdd0ec4a96 +Create Date: 2025-08-06 23:41:56.778423 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '197b195208e8' +down_revision: Union[str, None] = 'a2fdd0ec4a96' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade(): + """Upgrade schema.""" + op.execute("PRAGMA foreign_keys=ON") + + with op.batch_alter_table('tasks', schema=None) as batch_op: + connection = op.get_bind() + inspector = sa.inspect(connection) + + foreign_keys = inspector.get_foreign_keys('tasks') + constraint_name = None + + for fk in foreign_keys: + if 'user_id' in fk['constrained_columns']: + constraint_name = fk['name'] + break + + if constraint_name: + try: + batch_op.drop_constraint(constraint_name, type_='foreignkey') + except: + pass + + batch_op.create_foreign_key( + 'fk_tasks_user_id_users', + 'users', + ['user_id'], + ['id'], + ondelete='CASCADE' + ) + + +def downgrade(): + """Downgrade schema.""" + with op.batch_alter_table('tasks', schema=None) as batch_op: + try: + batch_op.drop_constraint('fk_tasks_user_id_users', type_='foreignkey') + except: + pass + + batch_op.create_foreign_key( + 'fk_tasks_user_id_users', + 'users', + ['user_id'], + ['id'] + ) diff --git a/src/migrations/versions/2025_08_06_2354-4b0f3ea2fd26_fix_duplicate_foreign_keys.py b/src/migrations/versions/2025_08_06_2354-4b0f3ea2fd26_fix_duplicate_foreign_keys.py new file mode 100644 index 0000000..66d8110 --- /dev/null +++ b/src/migrations/versions/2025_08_06_2354-4b0f3ea2fd26_fix_duplicate_foreign_keys.py @@ -0,0 +1,59 @@ +"""fix_duplicate_foreign_keys + +Revision ID: 4b0f3ea2fd26 +Revises: 197b195208e8 +Create Date: 2025-08-06 23:54:24.308488 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '4b0f3ea2fd26' +down_revision: Union[str, None] = '197b195208e8' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade(): + """Upgrade schema.""" + op.execute("PRAGMA foreign_keys=ON") + + with op.batch_alter_table('tasks', schema=None) as batch_op: + connection = op.get_bind() + inspector = sa.inspect(connection) + + foreign_keys = inspector.get_foreign_keys('tasks') + + for fk in foreign_keys: + if 'user_id' in fk['constrained_columns']: + try: + batch_op.drop_constraint(fk['name'], type_='foreignkey') + except: + pass + + batch_op.create_foreign_key( + 'fk_tasks_user_id_users', + 'users', + ['user_id'], + ['id'], + ondelete='CASCADE' + ) + + +def downgrade(): + """Downgrade schema.""" + with op.batch_alter_table('tasks', schema=None) as batch_op: + try: + batch_op.drop_constraint('fk_tasks_user_id_users', type_='foreignkey') + except: + pass + batch_op.create_foreign_key( + 'fk_tasks_user_id_users', + 'users', + ['user_id'], + ['id'] + ) diff --git a/src/models/tasks.py b/src/models/tasks.py index b000446..fb82743 100644 --- a/src/models/tasks.py +++ b/src/models/tasks.py @@ -16,7 +16,7 @@ priority_enum = Enum("low", "medium", "high", "critical", name="priority_enum") class TasksORM(Base): __tablename__ = "tasks" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) - user_id: Mapped[int] = mapped_column(ForeignKey("users.id")) + user_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE")) title: Mapped[str] = mapped_column(String(100)) description: Mapped[Optional[str]] = mapped_column(Text, nullable=True) due_date: Mapped[Optional[date]] = mapped_column(Date, nullable=True) diff --git a/src/models/users.py b/src/models/users.py index 9958677..d11aa13 100644 --- a/src/models/users.py +++ b/src/models/users.py @@ -23,4 +23,4 @@ class UsersORM(Base): avatar_path: Mapped[Optional[str]] = mapped_column(String(255), nullable=True) is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) is_superuser: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) - tasks: Mapped[list["TasksORM"]] = relationship(back_populates="user") + tasks: Mapped[list["TasksORM"]] = relationship(back_populates="user", cascade="all, delete-orphan")