Suppression ref. comp. et dept: cascades.

This commit is contained in:
Emmanuel Viennet 2023-02-09 11:56:20 +01:00
parent 2ce0968614
commit cd1e6aa73d
11 changed files with 508 additions and 52 deletions

View File

@ -53,7 +53,9 @@ class XMLModel:
class ApcReferentielCompetences(db.Model, XMLModel):
"Référentiel de compétence d'une spécialité"
id = db.Column(db.Integer, primary_key=True)
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
dept_id = db.Column(
db.Integer, db.ForeignKey("departement.id", ondelete="CASCADE"), index=True
)
annexe = db.Column(db.Text()) # '1', '22', ...
specialite = db.Column(db.Text()) # 'CJ', 'RT', 'INFO', ...
specialite_long = db.Column(
@ -207,7 +209,9 @@ class ApcCompetence(db.Model, XMLModel):
"Compétence"
id = db.Column(db.Integer, primary_key=True)
referentiel_id = db.Column(
db.Integer, db.ForeignKey("apc_referentiel_competences.id"), nullable=False
db.Integer,
db.ForeignKey("apc_referentiel_competences.id", ondelete="CASCADE"),
nullable=False,
)
# les compétences dans Orébut sont identifiées par leur id unique
# (mais id_orebut n'est pas unique car le même ref. pourra être chargé dans plusieurs depts)
@ -276,7 +280,9 @@ class ApcSituationPro(db.Model, XMLModel):
"Situation professionnelle"
id = db.Column(db.Integer, primary_key=True)
competence_id = db.Column(
db.Integer, db.ForeignKey("apc_competence.id"), nullable=False
db.Integer,
db.ForeignKey("apc_competence.id", ondelete="CASCADE"),
nullable=False,
)
libelle = db.Column(db.Text(), nullable=False)
# aucun attribut (le text devient le libellé)
@ -288,7 +294,9 @@ class ApcComposanteEssentielle(db.Model, XMLModel):
"Composante essentielle"
id = db.Column(db.Integer, primary_key=True)
competence_id = db.Column(
db.Integer, db.ForeignKey("apc_competence.id"), nullable=False
db.Integer,
db.ForeignKey("apc_competence.id", ondelete="CASCADE"),
nullable=False,
)
libelle = db.Column(db.Text(), nullable=False)
@ -306,7 +314,9 @@ class ApcNiveau(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
competence_id = db.Column(
db.Integer, db.ForeignKey("apc_competence.id"), nullable=False
db.Integer,
db.ForeignKey("apc_competence.id", ondelete="CASCADE"),
nullable=False,
)
libelle = db.Column(db.Text(), nullable=False)
annee = db.Column(db.Text(), nullable=False) # "BUT1", "BUT2", "BUT3"
@ -387,7 +397,7 @@ app_critiques_modules = db.Table(
),
db.Column(
"app_crit_id",
db.ForeignKey("apc_app_critique.id"),
db.ForeignKey("apc_app_critique.id", ondelete="CASCADE"),
primary_key=True,
),
)
@ -396,7 +406,9 @@ app_critiques_modules = db.Table(
class ApcAppCritique(db.Model, XMLModel):
"Apprentissage Critique BUT"
id = db.Column(db.Integer, primary_key=True)
niveau_id = db.Column(db.Integer, db.ForeignKey("apc_niveau.id"), nullable=False)
niveau_id = db.Column(
db.Integer, db.ForeignKey("apc_niveau.id", ondelete="CASCADE"), nullable=False
)
code = db.Column(db.Text(), nullable=False, index=True)
libelle = db.Column(db.Text())
@ -445,7 +457,10 @@ class ApcAppCritique(db.Model, XMLModel):
parcours_modules = db.Table(
"parcours_modules",
db.Column(
"parcours_id", db.Integer, db.ForeignKey("apc_parcours.id"), primary_key=True
"parcours_id",
db.Integer,
db.ForeignKey("apc_parcours.id", ondelete="CASCADE"),
primary_key=True,
),
db.Column(
"module_id",
@ -459,7 +474,10 @@ parcours_modules = db.Table(
parcours_formsemestre = db.Table(
"parcours_formsemestre",
db.Column(
"parcours_id", db.Integer, db.ForeignKey("apc_parcours.id"), primary_key=True
"parcours_id",
db.Integer,
db.ForeignKey("apc_parcours.id", ondelete="CASCADE"),
primary_key=True,
),
db.Column(
"formsemestre_id",
@ -475,7 +493,9 @@ class ApcParcours(db.Model, XMLModel):
"Un parcours BUT"
id = db.Column(db.Integer, primary_key=True)
referentiel_id = db.Column(
db.Integer, db.ForeignKey("apc_referentiel_competences.id"), nullable=False
db.Integer,
db.ForeignKey("apc_referentiel_competences.id", ondelete="CASCADE"),
nullable=False,
)
numero = db.Column(db.Integer) # ordre de présentation
code = db.Column(db.Text(), nullable=False)
@ -516,7 +536,7 @@ class ApcParcours(db.Model, XMLModel):
class ApcAnneeParcours(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
parcours_id = db.Column(
db.Integer, db.ForeignKey("apc_parcours.id"), nullable=False
db.Integer, db.ForeignKey("apc_parcours.id", ondelete="CASCADE"), nullable=False
)
ordre = db.Column(db.Integer)
"numéro de l'année: 1, 2, 3"

View File

@ -46,7 +46,9 @@ class ApcValidationRCUE(db.Model):
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)
# optionnel, le parcours dans lequel se trouve la compétence:
parcours_id = db.Column(db.Integer, db.ForeignKey("apc_parcours.id"), nullable=True)
parcours_id = db.Column(
db.Integer, db.ForeignKey("apc_parcours.id", ondelete="set null"), nullable=True
)
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
code = db.Column(db.String(CODE_STR_LEN), nullable=False, index=True)

View File

@ -48,7 +48,7 @@ class Formation(db.Model):
# Optionnel, pour les formations type BUT
referentiel_competence_id = db.Column(
db.Integer, db.ForeignKey("apc_referentiel_competences.id")
db.Integer, db.ForeignKey("apc_referentiel_competences.id", ondelete="SET NULL")
)
ues = db.relationship("UniteEns", backref="formation", lazy="dynamic")
formsemestres = db.relationship("FormSemestre", lazy="dynamic", backref="formation")

View File

@ -1037,7 +1037,9 @@ class FormSemestreInscription(db.Model):
# Etape Apogée d'inscription (ajout 2020)
etape = db.Column(db.String(APO_CODE_STR_LEN))
# Parcours (pour les BUT)
parcour_id = db.Column(db.Integer, db.ForeignKey("apc_parcours.id"), index=True)
parcour_id = db.Column(
db.Integer, db.ForeignKey("apc_parcours.id", ondelete="SET NULL"), index=True
)
parcour = db.relationship(ApcParcours)
def __repr__(self):

View File

@ -51,11 +51,15 @@ class UniteEns(db.Model):
color = db.Column(db.Text())
# BUT
niveau_competence_id = db.Column(db.Integer, db.ForeignKey("apc_niveau.id"))
niveau_competence_id = db.Column(
db.Integer, db.ForeignKey("apc_niveau.id", ondelete="SET NULL")
)
niveau_competence = db.relationship("ApcNiveau", back_populates="ues")
# Une ue appartient soit à tous les parcours (tronc commun), soit à un seul:
parcour_id = db.Column(db.Integer, db.ForeignKey("apc_parcours.id"), index=True)
parcour_id = db.Column(
db.Integer, db.ForeignKey("apc_parcours.id", ondelete="SET NULL"), index=True
)
parcour = db.relationship("ApcParcours", back_populates="ues")
# relations

View File

@ -160,11 +160,11 @@ class ScolarEvent(db.Model):
event_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
formsemestre_id = db.Column(
db.Integer,
db.ForeignKey("notes_formsemestre.id"),
db.ForeignKey("notes_formsemestre.id", ondelete="SET NULL"),
)
ue_id = db.Column(
db.Integer,
db.ForeignKey("notes_ue.id"),
db.ForeignKey("notes_ue.id", ondelete="SET NULL"),
)
# 'CREATION', 'INSCRIPTION', 'DEMISSION',
# 'AUT_RED', 'EXCLUS', 'VALID_UE', 'VALID_SEM'

View File

@ -317,7 +317,7 @@ def _style_sems(sems):
] = f""" data-oid="{sem['formsemestre_id']}" data-value="{sem['elt_sem_apo']}" """
def delete_dept(dept_id: int):
def delete_dept(dept_id: int) -> str:
"""Suppression irréversible d'un département et de tous les objets rattachés"""
assert isinstance(dept_id, int)
@ -361,6 +361,7 @@ def delete_dept(dept_id: int):
)
reqs = [
"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)",
@ -392,8 +393,10 @@ def delete_dept(dept_id: int):
]
for r in reqs:
cursor.execute(r, {"dept_id": dept_id})
except:
except Exception as e:
cnx.rollback()
return str(e)
finally:
cnx.commit()
app.clear_scodoc_cache()
return ""

View File

@ -28,8 +28,8 @@
"""Dump base de données pour debug et support technique
Le principe est le suivant:
1- S'il existe une base en cours d'anonymisation, s'arrête et affiche un msg d'erreur l'utilisateur,
qui peut décider de la supprimer.
1- S'il existe une base en cours d'anonymisation, s'arrête et affiche un msg
d'erreur à l'utilisateur, qui peut décider de la supprimer.
2- ScoDoc lance un script qui duplique la base (la copie de SCORT devient ANORT)
- (si elle existe deja, s'arrête)
@ -49,9 +49,9 @@ pg_dump SCORT | psql ANORT
import base64
import fcntl
import os
import requests
import subprocess
import traceback
import requests
from flask import g, request
from flask_login import current_user
@ -59,9 +59,8 @@ from flask_login import current_user
import app.scodoc.notesdb as ndb
import app.scodoc.sco_utils as scu
from app import log
from app.scodoc import sco_users
import sco_version
from app.scodoc.sco_exceptions import ScoValueError
import sco_version
SCO_DUMP_LOCK = "/tmp/scodump.lock"
@ -81,12 +80,10 @@ def sco_dump_and_send_db(
try:
x = open(SCO_DUMP_LOCK, "w+")
fcntl.flock(x, fcntl.LOCK_EX | fcntl.LOCK_NB)
except (IOError, OSError):
except (IOError, OSError) as e:
raise ScoValueError(
"Un envoi de la base "
+ db_name
+ " est déjà en cours, re-essayer plus tard"
)
"Un envoi de la base {db_name} est déjà en cours, re-essayer plus tard"
) from e
try:
# Drop if exists
@ -96,7 +93,7 @@ def sco_dump_and_send_db(
_duplicate_db(db_name, ano_db_name)
# Anonymisation
_anonymize_db(ano_db_name)
anonymize_db(ano_db_name)
# Send
r = _send_db(ano_db_name, message, request_url, traceback_str=traceback_str)
@ -116,44 +113,44 @@ def sco_dump_and_send_db(
def _duplicate_db(db_name, ano_db_name):
"""Create new database, and copy old one into"""
cmd = ["createdb", "-E", "UTF-8", ano_db_name]
log("sco_dump_and_send_db/_duplicate_db: {}".format(cmd))
log(f"sco_dump_and_send_db/_duplicate_db: {cmd}")
try:
_ = subprocess.check_output(cmd)
except subprocess.CalledProcessError as e:
log("sco_dump_and_send_db: exception createdb {}".format(e))
log(f"sco_dump_and_send_db: exception createdb {e}")
raise ScoValueError(
"erreur lors de la creation de la base {}".format(ano_db_name)
)
f"erreur lors de la creation de la base {ano_db_name}"
) from e
cmd = "pg_dump {} | psql {}".format(db_name, ano_db_name)
cmd = f"pg_dump {db_name} | psql {ano_db_name}"
log("sco_dump_and_send_db/_duplicate_db: {}".format(cmd))
try:
_ = subprocess.check_output(cmd, shell=1)
except subprocess.CalledProcessError as e:
log("sco_dump_and_send_db: exception {}".format(e))
raise ScoValueError(
"erreur lors de la duplication de la base {} vers {}".format(
db_name, ano_db_name
)
)
f"erreur lors de la duplication de la base {db_name} vers {ano_db_name}"
) from e
def _anonymize_db(ano_db_name):
"""Anonymize a departement database"""
def anonymize_db(ano_db_name):
"""Anonymize a ScoDoc database"""
cmd = os.path.join(scu.SCO_TOOLS_DIR, "anonymize_db.py")
log("_anonymize_db: {}".format(cmd))
log(f"anonymize_db: {cmd}")
try:
_ = subprocess.check_output([cmd, ano_db_name])
except subprocess.CalledProcessError as e:
log("sco_dump_and_send_db: exception in anonymisation: {}".format(e))
log(f"sco_dump_and_send_db: exception in anonymisation: {e}")
raise ScoValueError(
"erreur lors de l'anonymisation de la base {}".format(ano_db_name)
)
f"erreur lors de l'anonymisation de la base {ano_db_name}"
) from e
def _get_scodoc_serial():
try:
with open(os.path.join(scu.SCODOC_VERSION_DIR, "scodoc.sn")) as f:
with open(
os.path.join(scu.SCODOC_VERSION_DIR, "scodoc.sn"), encoding=scu.SCO_ENCODING
) as f:
return int(f.read())
except:
return 0

View File

@ -0,0 +1,415 @@
"""cascades ref. comp.
Revision ID: d8288b7f0a3e
Revises: 5c7b208355df
Create Date: 2023-02-09 11:25:28.879434
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "d8288b7f0a3e"
down_revision = "5c7b208355df"
branch_labels = ""
depends_on = ""
def upgrade():
# EVENTS
op.drop_constraint(
"scolar_events_formsemestre_id_fkey", "scolar_events", type_="foreignkey"
)
op.drop_constraint("scolar_events_ue_id_fkey", "scolar_events", type_="foreignkey")
op.create_foreign_key(
"scolar_events_ue_id_fkey",
"scolar_events",
"notes_ue",
["ue_id"],
["id"],
ondelete="SET NULL",
)
op.create_foreign_key(
"scolar_events_formsemestre_id_fkey",
"scolar_events",
"notes_formsemestre",
["formsemestre_id"],
["id"],
ondelete="SET NULL",
)
# REF COMP
op.drop_constraint(
"apc_annee_parcours_parcours_id_fkey", "apc_annee_parcours", type_="foreignkey"
)
op.create_foreign_key(
"apc_annee_parcours_parcours_id_fkey",
"apc_annee_parcours",
"apc_parcours",
["parcours_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"apc_app_critique_niveau_id_fkey", "apc_app_critique", type_="foreignkey"
)
op.create_foreign_key(
"apc_app_critique_niveau_id_fkey",
"apc_app_critique",
"apc_niveau",
["niveau_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"apc_competence_referentiel_id_fkey", "apc_competence", type_="foreignkey"
)
op.create_foreign_key(
"apc_competence_referentiel_id_fkey",
"apc_competence",
"apc_referentiel_competences",
["referentiel_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"apc_composante_essentielle_competence_id_fkey",
"apc_composante_essentielle",
type_="foreignkey",
)
op.create_foreign_key(
"apc_composante_essentielle_competence_id_fkey",
"apc_composante_essentielle",
"apc_competence",
["competence_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"apc_modules_acs_app_crit_id_fkey", "apc_modules_acs", type_="foreignkey"
)
op.create_foreign_key(
"apc_modules_acs_app_crit_id_fkey",
"apc_modules_acs",
"apc_app_critique",
["app_crit_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"apc_niveau_competence_id_fkey", "apc_niveau", type_="foreignkey"
)
op.create_foreign_key(
"apc_niveau_competence_id_fkey",
"apc_niveau",
"apc_competence",
["competence_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"apc_parcours_referentiel_id_fkey", "apc_parcours", type_="foreignkey"
)
op.create_foreign_key(
"apc_parcours_referentiel_id_fkey",
"apc_parcours",
"apc_referentiel_competences",
["referentiel_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"apc_referentiel_competences_dept_id_fkey",
"apc_referentiel_competences",
type_="foreignkey",
)
op.create_foreign_key(
"apc_referentiel_competences_dept_id_fkey",
"apc_referentiel_competences",
"departement",
["dept_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"apc_situation_pro_competence_id_fkey", "apc_situation_pro", type_="foreignkey"
)
op.create_foreign_key(
"apc_situation_pro_competence_id_fkey",
"apc_situation_pro",
"apc_competence",
["competence_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"apc_validation_rcue_parcours_id_fkey",
"apc_validation_rcue",
type_="foreignkey",
)
op.create_foreign_key(
"apc_validation_rcue_parcours_id_fkey",
"apc_validation_rcue",
"apc_parcours",
["parcours_id"],
["id"],
ondelete="set null",
)
op.drop_constraint(
"notes_formations_referentiel_competence_id_fkey",
"notes_formations",
type_="foreignkey",
)
op.create_foreign_key(
"notes_formations_referentiel_competence_id_fkey",
"notes_formations",
"apc_referentiel_competences",
["referentiel_competence_id"],
["id"],
ondelete="SET NULL",
)
op.drop_constraint(
"notes_formsemestre_inscription_parcour_id_fkey",
"notes_formsemestre_inscription",
type_="foreignkey",
)
op.create_foreign_key(
"notes_formsemestre_inscription_parcour_id_fkey",
"notes_formsemestre_inscription",
"apc_parcours",
["parcour_id"],
["id"],
ondelete="SET NULL",
)
op.drop_constraint(
"notes_ue_niveau_competence_id_fkey", "notes_ue", type_="foreignkey"
)
op.drop_constraint("notes_ue_parcour_id_fkey", "notes_ue", type_="foreignkey")
op.create_foreign_key(
"notes_ue_niveau_competence_id_fkey",
"notes_ue",
"apc_niveau",
["niveau_competence_id"],
["id"],
ondelete="SET NULL",
)
op.create_foreign_key(
"notes_ue_parcour_id_fkey",
"notes_ue",
"apc_parcours",
["parcour_id"],
["id"],
ondelete="SET NULL",
)
op.drop_constraint(
"parcours_formsemestre_parcours_id_fkey",
"parcours_formsemestre",
type_="foreignkey",
)
op.create_foreign_key(
"parcours_formsemestre_parcours_id_fkey",
"parcours_formsemestre",
"apc_parcours",
["parcours_id"],
["id"],
ondelete="CASCADE",
)
op.drop_constraint(
"parcours_modules_parcours_id_fkey", "parcours_modules", type_="foreignkey"
)
op.create_foreign_key(
"parcours_modules_parcours_id_fkey",
"parcours_modules",
"apc_parcours",
["parcours_id"],
["id"],
ondelete="CASCADE",
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(
"parcours_modules_parcours_id_fkey", "parcours_modules", type_="foreignkey"
)
op.create_foreign_key(
"parcours_modules_parcours_id_fkey",
"parcours_modules",
"apc_parcours",
["parcours_id"],
["id"],
)
op.drop_constraint(
"parcours_formsemestre_parcours_id_fkey",
"parcours_formsemestre",
type_="foreignkey",
)
op.create_foreign_key(
"parcours_formsemestre_parcours_id_fkey",
"parcours_formsemestre",
"apc_parcours",
["parcours_id"],
["id"],
)
op.drop_constraint("notes_ue_parcour_id_fkey", "notes_ue", type_="foreignkey")
op.drop_constraint(
"notes_ue_niveau_competence_id_fkey", "notes_ue", type_="foreignkey"
)
op.create_foreign_key(
"notes_ue_parcour_id_fkey", "notes_ue", "apc_parcours", ["parcour_id"], ["id"]
)
op.create_foreign_key(
"notes_ue_niveau_competence_id_fkey",
"notes_ue",
"apc_niveau",
["niveau_competence_id"],
["id"],
)
op.drop_constraint(
"notes_formsemestre_inscription_parcour_id_fkey",
"notes_formsemestre_inscription",
type_="foreignkey",
)
op.create_foreign_key(
"notes_formsemestre_inscription_parcour_id_fkey",
"notes_formsemestre_inscription",
"apc_parcours",
["parcour_id"],
["id"],
)
op.drop_constraint(
"notes_formations_referentiel_competence_id_fkey",
"notes_formations",
type_="foreignkey",
)
op.create_foreign_key(
"notes_formations_referentiel_competence_id_fkey",
"notes_formations",
"apc_referentiel_competences",
["referentiel_competence_id"],
["id"],
)
op.drop_constraint(
"apc_validation_rcue_parcours_id_fkey",
"apc_validation_rcue",
type_="foreignkey",
)
op.create_foreign_key(
"apc_validation_rcue_parcours_id_fkey",
"apc_validation_rcue",
"apc_parcours",
["parcours_id"],
["id"],
)
op.drop_constraint(
"apc_situation_pro_competence_id_fkey", "apc_situation_pro", type_="foreignkey"
)
op.create_foreign_key(
"apc_situation_pro_competence_id_fkey",
"apc_situation_pro",
"apc_competence",
["competence_id"],
["id"],
)
op.drop_constraint(
"apc_referentiel_competences_dept_id_fkey",
"apc_referentiel_competences",
type_="foreignkey",
)
op.create_foreign_key(
"apc_referentiel_competences_dept_id_fkey",
"apc_referentiel_competences",
"departement",
["dept_id"],
["id"],
)
op.drop_constraint(
"apc_parcours_referentiel_id_fkey", "apc_parcours", type_="foreignkey"
)
op.create_foreign_key(
"apc_parcours_referentiel_id_fkey",
"apc_parcours",
"apc_referentiel_competences",
["referentiel_id"],
["id"],
)
op.drop_constraint(
"apc_niveau_competence_id_fkey", "apc_niveau", type_="foreignkey"
)
op.create_foreign_key(
"apc_niveau_competence_id_fkey",
"apc_niveau",
"apc_competence",
["competence_id"],
["id"],
)
op.drop_constraint(
"apc_modules_acs_app_crit_id_fkey", "apc_modules_acs", type_="foreignkey"
)
op.create_foreign_key(
"apc_modules_acs_app_crit_id_fkey",
"apc_modules_acs",
"apc_app_critique",
["app_crit_id"],
["id"],
)
op.drop_constraint(
"apc_composante_essentielle_competence_id_fkey",
"apc_composante_essentielle",
type_="foreignkey",
)
op.create_foreign_key(
"apc_composante_essentielle_competence_id_fkey",
"apc_composante_essentielle",
"apc_competence",
["competence_id"],
["id"],
)
op.drop_constraint(
"apc_competence_referentiel_id_fkey", "apc_competence", type_="foreignkey"
)
op.create_foreign_key(
"apc_competence_referentiel_id_fkey",
"apc_competence",
"apc_referentiel_competences",
["referentiel_id"],
["id"],
)
op.drop_constraint(
"apc_app_critique_niveau_id_fkey", "apc_app_critique", type_="foreignkey"
)
op.create_foreign_key(
"apc_app_critique_niveau_id_fkey",
"apc_app_critique",
"apc_niveau",
["niveau_id"],
["id"],
)
op.drop_constraint(
"apc_annee_parcours_parcours_id_fkey", "apc_annee_parcours", type_="foreignkey"
)
op.create_foreign_key(
"apc_annee_parcours_parcours_id_fkey",
"apc_annee_parcours",
"apc_parcours",
["parcours_id"],
["id"],
)
# EVENTS
op.drop_constraint("scolar_events_ue_id_fkey", "scolar_events", type_="foreignkey")
op.drop_constraint(
"scolar_events_formsemestre_id_fkey", "scolar_events", type_="foreignkey"
)
op.create_foreign_key(
"scolar_events_ue_id_fkey", "scolar_events", "notes_ue", ["ue_id"], ["id"]
)
op.create_foreign_key(
"scolar_events_formsemestre_id_fkey",
"scolar_events",
"notes_formsemestre",
["formsemestre_id"],
["id"],
)
# ### end Alembic commands ###

View File

@ -41,6 +41,7 @@ from app.models.but_refcomp import (
)
from app.models.but_validations import ApcValidationAnnee, ApcValidationRCUE
from app.models.evaluations import Evaluation
from app.scodoc import sco_dump_db
from app.scodoc.sco_logos import make_logo_local
from app.scodoc.sco_permissions import Permission
from app.views import notes, scolar
@ -131,6 +132,18 @@ def sco_db_init(erase=False): # sco-db-init
initialize_scodoc_database(erase=erase)
@app.cli.command()
@click.argument("database")
def anonymize_db(database): # anonymize-db
"""Anonymise la base de nom indiqué (et non pas la base courante!)"""
click.confirm(
f"L'anonymisation va affecter la base {database} et PERDRE beaucoup de données.\nContinuer ?",
abort=True,
)
sco_dump_db.anonymize_db(database)
click.echo(f"Base {database} pseudonymisée")
@app.cli.command()
def user_db_clear():
"""Erase all users and roles from the database !"""
@ -397,9 +410,11 @@ def delete_dept(dept, force=False): # delete-dept
sys.stderr.write(f"Erreur: le departement {dept} n'existe pas !\n")
return 2
elif d:
sco_dept.delete_dept(d.id)
msg = sco_dept.delete_dept(d.id)
db.session.commit()
return 0
if msg:
print(f"Erreur:\n {msg}")
return 0 if not msg else 1
@app.cli.command()

View File

@ -26,8 +26,6 @@
#
##############################################################################
# TODO à tester avec ScoDoc9, devrait fonctionner sans problème majeur ?
"""Anonymize une base de données ScoDoc
Runned as user "scodoc" with scodoc and postgresql up.