Corrige cascades sur Identite.

This commit is contained in:
Emmanuel Viennet 2023-10-25 23:07:34 +02:00
parent 3ad9ab15d5
commit 20d19a190d
8 changed files with 152 additions and 57 deletions

View File

@ -97,6 +97,7 @@ class ApcReferentielCompetences(db.Model, XMLModel):
validations_annee = db.relationship(
"ApcValidationAnnee",
backref="referentiel_competence",
cascade="all, delete-orphan", # cascade at ORM level
lazy="dynamic",
)

View File

@ -38,8 +38,12 @@ class ApcValidationRCUE(db.Model):
)
"formsemestre origine du RCUE (celui d'où a été émis la validation)"
# Les deux UE associées à ce niveau:
ue1_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
ue2_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
ue1_id = db.Column(
db.Integer, db.ForeignKey("notes_ue.id", ondelete="CASCADE"), nullable=False
)
ue2_id = db.Column(
db.Integer, db.ForeignKey("notes_ue.id", ondelete="CASCADE"), nullable=False
)
# optionnel, le parcours dans lequel se trouve la compétence:
parcours_id = db.Column(
db.Integer, db.ForeignKey("apc_parcours.id", ondelete="set null"), nullable=True

View File

@ -30,15 +30,17 @@ class Identite(db.Model, models.ScoDocModel):
id = db.Column(db.Integer, primary_key=True)
etudid = db.synonym("id")
admission_id = db.Column(db.Integer, db.ForeignKey("admissions.id"), nullable=True)
# ForeignKey ondelete set the cascade at the database level
admission_id = db.Column(
db.Integer, db.ForeignKey("admissions.id", ondelete="CASCADE"), nullable=True
)
admission = db.relationship(
"Admission",
back_populates="etud",
uselist=False,
cascade="all,delete",
cascade="all,delete", # cascade also defined at ORM level
single_parent=True,
)
dept_id = db.Column(
db.Integer, db.ForeignKey("departement.id"), index=True, nullable=False
)

View File

@ -28,11 +28,12 @@
"""Page accueil département (liste des semestres, etc)
"""
from flask import g, request
from flask import g
from flask import url_for
from flask_login import current_user
import app
from app import log
from app.models import ScolarNews
import app.scodoc.sco_utils as scu
from app.scodoc.gen_tables import GenTable
@ -329,12 +330,16 @@ def delete_dept(dept_id: int) -> str:
# 1- Create temp tables to store ids
reqs = [
"create temp table etudids_temp as select id from identite where dept_id = %(dept_id)s",
"create temp table formsemestres_temp as select id from notes_formsemestre where dept_id = %(dept_id)s",
"create temp table moduleimpls_temp as select id from notes_moduleimpl where formsemestre_id in (select id from formsemestres_temp)",
"create temp table formations_temp as select id from notes_formations where dept_id = %(dept_id)s",
"""create temp table formsemestres_temp as select id
from notes_formsemestre where dept_id = %(dept_id)s""",
"""create temp table moduleimpls_temp as select id from notes_moduleimpl
where formsemestre_id in (select id from formsemestres_temp)""",
"""create temp table formations_temp as
select id from notes_formations where dept_id = %(dept_id)s""",
"create temp table tags_temp as select id from notes_tags where dept_id = %(dept_id)s",
]
for r in reqs:
log(f"delete_dept: {r}")
cursor.execute(r, {"dept_id": dept_id})
# 2- Delete student-related informations
@ -342,7 +347,6 @@ def delete_dept(dept_id: int) -> str:
etud_tables = [
"notes_notes",
"group_membership",
"admissions",
"billet_absence",
"adresse",
"absences",
@ -357,29 +361,45 @@ def delete_dept(dept_id: int) -> str:
"scolar_events",
]
for table in etud_tables:
log(f"delete from {table}")
cursor.execute(
f"delete from {table} where etudid in (select id from etudids_temp)"
)
reqs = [
"""delete from apc_validation_annee where referentiel_competence_id
in (select id from apc_referentiel_competences where dept_id = %(dept_id)s)""",
"delete from apc_referentiel_competences where dept_id = %(dept_id)s",
"delete from identite where dept_id = %(dept_id)s",
"delete from sco_prefs where dept_id = %(dept_id)s",
"delete from notes_semset_formsemestre where formsemestre_id in (select id from formsemestres_temp)",
"delete from notes_evaluation where moduleimpl_id in (select id from moduleimpls_temp)",
"delete from notes_modules_enseignants where moduleimpl_id in (select id from moduleimpls_temp)",
"delete from notes_formsemestre_uecoef where formsemestre_id in (select id from formsemestres_temp)",
"delete from notes_formsemestre_ue_computation_expr where formsemestre_id in (select id from formsemestres_temp)",
"delete from notes_formsemestre_responsables where formsemestre_id in (select id from formsemestres_temp)",
"delete from notes_moduleimpl where formsemestre_id in (select id from formsemestres_temp)",
"delete from notes_modules_tags where tag_id in (select id from tags_temp)",
"""delete from notes_semset_formsemestre
where formsemestre_id in (select id from formsemestres_temp)""",
"""delete from notes_evaluation
where moduleimpl_id in (select id from moduleimpls_temp)""",
"""delete from notes_modules_enseignants
where moduleimpl_id in (select id from moduleimpls_temp)""",
"""delete from notes_formsemestre_uecoef
where formsemestre_id in (select id from formsemestres_temp)""",
"""delete from notes_formsemestre_ue_computation_expr
where formsemestre_id in (select id from formsemestres_temp)""",
"""delete from notes_formsemestre_responsables
where formsemestre_id in (select id from formsemestres_temp)""",
"""delete from notes_moduleimpl
where formsemestre_id in (select id from formsemestres_temp)""",
"""delete from notes_modules_tags
where tag_id in (select id from tags_temp)""",
"delete from notes_tags where dept_id = %(dept_id)s",
"delete from notes_modules where formation_id in (select id from formations_temp)",
"delete from notes_matieres where ue_id in (select id from notes_ue where formation_id in (select id from formations_temp))",
"delete from notes_formsemestre_etapes where formsemestre_id in (select id from formsemestres_temp)",
"delete from group_descr where partition_id in (select id from partition where formsemestre_id in (select id from formsemestres_temp))",
"""delete from notes_matieres
where ue_id in (select id from notes_ue
where formation_id in (select id from formations_temp))""",
"""delete from notes_formsemestre_etapes
where formsemestre_id in (select id from formsemestres_temp)""",
"""delete from group_descr where partition_id in
(select id from partition
where formsemestre_id in (select id from formsemestres_temp))""",
"delete from partition where formsemestre_id in (select id from formsemestres_temp)",
"delete from notes_formsemestre_custommenu where formsemestre_id in (select id from formsemestres_temp)",
"""delete from notes_formsemestre_custommenu
where formsemestre_id in (select id from formsemestres_temp)""",
"delete from notes_ue where formation_id in (select id from formations_temp)",
"delete from notes_formsemestre where dept_id = %(dept_id)s",
"delete from scolar_news where dept_id = %(dept_id)s",
@ -393,6 +413,7 @@ def delete_dept(dept_id: int) -> str:
"drop table formsemestres_temp",
]
for r in reqs:
log(f"delete_dept: {r}")
cursor.execute(r, {"dept_id": dept_id})
except Exception as e:
cnx.rollback()

View File

@ -464,9 +464,6 @@ def scolars_import_excel_file(
cursor.execute(
"delete from adresse where etudid=%(etudid)s", {"etudid": etudid}
)
cursor.execute(
"delete from admissions where etudid=%(etudid)s", {"etudid": etudid}
)
cursor.execute(
"delete from group_membership where etudid=%(etudid)s",
{"etudid": etudid},

View File

@ -696,9 +696,6 @@ def do_import_etuds_from_portal(sem, a_importer, etudsapo_ident):
cursor.execute(
"delete from adresse where etudid=%(etudid)s", {"etudid": etudid}
)
cursor.execute(
"delete from admissions where etudid=%(etudid)s", {"etudid": etudid}
)
cursor.execute(
"delete from group_membership where etudid=%(etudid)s",
{"etudid": etudid},

View File

@ -1896,6 +1896,7 @@ def etudident_delete(etudid, dialog_confirmed=False):
)
log("etudident_delete: etudid=%(etudid)s nomprenom=%(nomprenom)s" % etud)
# delete in all tables !
# c'est l'ancienne façon de gérer les cascades dans notre pseudo-ORM :)
tables = [
"notes_appreciations",
"scolar_autorisation_inscription",
@ -1908,7 +1909,6 @@ def etudident_delete(etudid, dialog_confirmed=False):
"group_membership",
"etud_annotations",
"scolog",
"admissions",
"adresse",
"absences",
"absences_notifications",

View File

@ -0,0 +1,73 @@
"""Ajoute quelques cascades oubliées
Revision ID: fd805feb7ba8
Revises: 497ba81343f7
Create Date: 2023-10-25 18:27:13.222354
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "fd805feb7ba8"
down_revision = "497ba81343f7"
branch_labels = None
depends_on = None
def upgrade():
with op.batch_alter_table("admissions", schema=None) as batch_op:
batch_op.drop_column("etudid")
with op.batch_alter_table("identite", schema=None) as batch_op:
batch_op.drop_constraint("admissions_etudid_fkey", type_="foreignkey")
batch_op.create_foreign_key(
"admissions_etudid_fkey",
"admissions",
["admission_id"],
["id"],
ondelete="CASCADE",
)
with op.batch_alter_table("apc_validation_rcue", schema=None) as batch_op:
batch_op.drop_constraint("apc_validation_rcue_ue1_id_fkey", type_="foreignkey")
batch_op.drop_constraint("apc_validation_rcue_ue2_id_fkey", type_="foreignkey")
batch_op.create_foreign_key(
"apc_validation_rcue_ue1_id_fkey",
"notes_ue",
["ue1_id"],
["id"],
ondelete="CASCADE",
)
batch_op.create_foreign_key(
"apc_validation_rcue_ue2_id_fkey",
"notes_ue",
["ue2_id"],
["id"],
ondelete="CASCADE",
)
def downgrade():
with op.batch_alter_table("identite", schema=None) as batch_op:
batch_op.drop_constraint("identite_dept_id_fkey", type_="foreignkey")
batch_op.drop_constraint("admissions_etudid_fkey", type_="foreignkey")
batch_op.create_foreign_key(
"admissions_etudid_fkey", "admissions", ["admission_id"], ["id"]
)
with op.batch_alter_table("admissions", schema=None) as batch_op:
batch_op.add_column(
sa.Column("etudid", sa.INTEGER(), autoincrement=False, nullable=True)
)
with op.batch_alter_table("apc_validation_rcue", schema=None) as batch_op:
batch_op.drop_constraint("apc_validation_rcue_ue1_id_fkey", type_="foreignkey")
batch_op.drop_constraint("apc_validation_rcue_ue2_id_fkey", type_="foreignkey")
batch_op.create_foreign_key(
"apc_validation_rcue_ue2_id_fkey", "notes_ue", ["ue2_id"], ["id"]
)
batch_op.create_foreign_key(
"apc_validation_rcue_ue1_id_fkey", "notes_ue", ["ue1_id"], ["id"]
)