diff --git a/alembic/env.py b/alembic/env.py index 347ff3f..4f34ce8 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -28,6 +28,7 @@ def run_migrations_offline() -> None: context.configure( url=url, target_metadata=target_metadata, + render_as_batch=True, literal_binds=True, dialect_opts={"paramstyle": "named"}, ) @@ -50,7 +51,10 @@ def run_migrations_online() -> None: ) with connectable.connect() as connection: - context.configure(connection=connection, target_metadata=target_metadata) + context.configure(connection=connection, + target_metadata=target_metadata, + render_as_batch=True, + ) with context.begin_transaction(): context.run_migrations() diff --git a/alembic/versions/7d480e6f1112_initial_migrations.py b/alembic/versions/7d480e6f1112_initial_migrations.py index 87bb415..3382fe1 100644 --- a/alembic/versions/7d480e6f1112_initial_migrations.py +++ b/alembic/versions/7d480e6f1112_initial_migrations.py @@ -53,6 +53,7 @@ def upgrade() -> None: sa.ForeignKeyConstraint( ["task_id"], ["tasks.id"], + name="results_task_id_fkey", ), sa.PrimaryKeyConstraint("id"), ) diff --git a/alembic/versions/defda3f2952d_add_on_delete_cascade_to_results_task_id.py b/alembic/versions/defda3f2952d_add_on_delete_cascade_to_results_task_id.py new file mode 100644 index 0000000..777cfa2 --- /dev/null +++ b/alembic/versions/defda3f2952d_add_on_delete_cascade_to_results_task_id.py @@ -0,0 +1,33 @@ +"""Add ON DELETE CASCADE to results’ task_id + +Revision ID: defda3f2952d +Revises: 1a3497f9f71b +Create Date: 2024-03-18 15:09:34.544573 + +""" +from typing import Sequence, Union + +from alembic import op + + +# revision identifiers, used by Alembic. +revision: str = 'defda3f2952d' +down_revision: Union[str, None] = '1a3497f9f71b' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + with op.batch_alter_table('results', schema=None) as batch_op: + batch_op.drop_constraint('results_task_id_fkey', type_='foreignkey') + batch_op.create_foreign_key('results_task_id_fkey', + 'tasks', + ['task_id'], + ['id'], + ondelete='CASCADE') + + +def downgrade() -> None: + with op.batch_alter_table('results', schema=None) as batch_op: + batch_op.drop_constraint('results_task_id_fkey', type_='foreignkey') + batch_op.create_foreign_key('results_task_id_fkey', 'tasks', ['task_id'], ['id']) diff --git a/argos/server/main.py b/argos/server/main.py index d3e175e..78eff8d 100644 --- a/argos/server/main.py +++ b/argos/server/main.py @@ -3,7 +3,7 @@ import sys from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from pydantic import ValidationError -from sqlalchemy import create_engine +from sqlalchemy import create_engine, event from sqlalchemy.orm import sessionmaker from argos.logging import logger @@ -94,6 +94,13 @@ def setup_database(appli): settings.database_url, **extra_settings ) + + def _fk_pragma_on_connect(dbapi_con, con_record): + dbapi_con.execute('pragma foreign_keys=ON') + + if settings.database_url.startswith("sqlite:////"): + event.listen(engine, 'connect', _fk_pragma_on_connect) + appli.state.SessionLocal = sessionmaker( autocommit=False, autoflush=False, bind=engine ) diff --git a/argos/server/models.py b/argos/server/models.py index 75ed8ab..866ccd6 100644 --- a/argos/server/models.py +++ b/argos/server/models.py @@ -47,7 +47,9 @@ class Task(Base): ) last_severity_update: Mapped[datetime] = mapped_column(nullable=True) - results: Mapped[List["Result"]] = relationship(back_populates="task") + results: Mapped[List["Result"]] = relationship(back_populates="task", + cascade="all, delete", + passive_deletes=True,) def __str__(self): return f"DB Task {self.url} - {self.check} - {self.expected}" @@ -92,9 +94,8 @@ class Result(Base): """ __tablename__ = "results" id: Mapped[int] = mapped_column(primary_key=True) - task_id: Mapped[int] = mapped_column(ForeignKey("tasks.id")) - task: Mapped["Task"] = relationship(back_populates="results", - cascade="save-update, merge, delete") + task_id: Mapped[int] = mapped_column(ForeignKey("tasks.id", ondelete="CASCADE")) + task: Mapped["Task"] = relationship(back_populates="results") agent_id: Mapped[str] = mapped_column(nullable=True) submitted_at: Mapped[datetime] = mapped_column()