forked from ScoDoc/ScoDoc
Suppression ref. comp. et dept: cascades.
This commit is contained in:
parent
2ce0968614
commit
cd1e6aa73d
@ -53,7 +53,9 @@ class XMLModel:
|
|||||||
class ApcReferentielCompetences(db.Model, XMLModel):
|
class ApcReferentielCompetences(db.Model, XMLModel):
|
||||||
"Référentiel de compétence d'une spécialité"
|
"Référentiel de compétence d'une spécialité"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
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', ...
|
annexe = db.Column(db.Text()) # '1', '22', ...
|
||||||
specialite = db.Column(db.Text()) # 'CJ', 'RT', 'INFO', ...
|
specialite = db.Column(db.Text()) # 'CJ', 'RT', 'INFO', ...
|
||||||
specialite_long = db.Column(
|
specialite_long = db.Column(
|
||||||
@ -207,7 +209,9 @@ class ApcCompetence(db.Model, XMLModel):
|
|||||||
"Compétence"
|
"Compétence"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
referentiel_id = db.Column(
|
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
|
# 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)
|
# (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"
|
"Situation professionnelle"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
competence_id = db.Column(
|
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)
|
libelle = db.Column(db.Text(), nullable=False)
|
||||||
# aucun attribut (le text devient le libellé)
|
# aucun attribut (le text devient le libellé)
|
||||||
@ -288,7 +294,9 @@ class ApcComposanteEssentielle(db.Model, XMLModel):
|
|||||||
"Composante essentielle"
|
"Composante essentielle"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
competence_id = db.Column(
|
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)
|
libelle = db.Column(db.Text(), nullable=False)
|
||||||
|
|
||||||
@ -306,7 +314,9 @@ class ApcNiveau(db.Model, XMLModel):
|
|||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
competence_id = db.Column(
|
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)
|
libelle = db.Column(db.Text(), nullable=False)
|
||||||
annee = db.Column(db.Text(), nullable=False) # "BUT1", "BUT2", "BUT3"
|
annee = db.Column(db.Text(), nullable=False) # "BUT1", "BUT2", "BUT3"
|
||||||
@ -387,7 +397,7 @@ app_critiques_modules = db.Table(
|
|||||||
),
|
),
|
||||||
db.Column(
|
db.Column(
|
||||||
"app_crit_id",
|
"app_crit_id",
|
||||||
db.ForeignKey("apc_app_critique.id"),
|
db.ForeignKey("apc_app_critique.id", ondelete="CASCADE"),
|
||||||
primary_key=True,
|
primary_key=True,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -396,7 +406,9 @@ app_critiques_modules = db.Table(
|
|||||||
class ApcAppCritique(db.Model, XMLModel):
|
class ApcAppCritique(db.Model, XMLModel):
|
||||||
"Apprentissage Critique BUT"
|
"Apprentissage Critique BUT"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
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)
|
code = db.Column(db.Text(), nullable=False, index=True)
|
||||||
libelle = db.Column(db.Text())
|
libelle = db.Column(db.Text())
|
||||||
|
|
||||||
@ -445,7 +457,10 @@ class ApcAppCritique(db.Model, XMLModel):
|
|||||||
parcours_modules = db.Table(
|
parcours_modules = db.Table(
|
||||||
"parcours_modules",
|
"parcours_modules",
|
||||||
db.Column(
|
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(
|
db.Column(
|
||||||
"module_id",
|
"module_id",
|
||||||
@ -459,7 +474,10 @@ parcours_modules = db.Table(
|
|||||||
parcours_formsemestre = db.Table(
|
parcours_formsemestre = db.Table(
|
||||||
"parcours_formsemestre",
|
"parcours_formsemestre",
|
||||||
db.Column(
|
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(
|
db.Column(
|
||||||
"formsemestre_id",
|
"formsemestre_id",
|
||||||
@ -475,7 +493,9 @@ class ApcParcours(db.Model, XMLModel):
|
|||||||
"Un parcours BUT"
|
"Un parcours BUT"
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
referentiel_id = db.Column(
|
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
|
numero = db.Column(db.Integer) # ordre de présentation
|
||||||
code = db.Column(db.Text(), nullable=False)
|
code = db.Column(db.Text(), nullable=False)
|
||||||
@ -516,7 +536,7 @@ class ApcParcours(db.Model, XMLModel):
|
|||||||
class ApcAnneeParcours(db.Model, XMLModel):
|
class ApcAnneeParcours(db.Model, XMLModel):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
parcours_id = db.Column(
|
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)
|
ordre = db.Column(db.Integer)
|
||||||
"numéro de l'année: 1, 2, 3"
|
"numéro de l'année: 1, 2, 3"
|
||||||
|
@ -46,7 +46,9 @@ class ApcValidationRCUE(db.Model):
|
|||||||
ue1_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
|
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)
|
ue2_id = db.Column(db.Integer, db.ForeignKey("notes_ue.id"), nullable=False)
|
||||||
# optionnel, le parcours dans lequel se trouve la compétence:
|
# 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())
|
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||||
code = db.Column(db.String(CODE_STR_LEN), nullable=False, index=True)
|
code = db.Column(db.String(CODE_STR_LEN), nullable=False, index=True)
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class Formation(db.Model):
|
|||||||
|
|
||||||
# Optionnel, pour les formations type BUT
|
# Optionnel, pour les formations type BUT
|
||||||
referentiel_competence_id = db.Column(
|
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")
|
ues = db.relationship("UniteEns", backref="formation", lazy="dynamic")
|
||||||
formsemestres = db.relationship("FormSemestre", lazy="dynamic", backref="formation")
|
formsemestres = db.relationship("FormSemestre", lazy="dynamic", backref="formation")
|
||||||
|
@ -1037,7 +1037,9 @@ class FormSemestreInscription(db.Model):
|
|||||||
# Etape Apogée d'inscription (ajout 2020)
|
# Etape Apogée d'inscription (ajout 2020)
|
||||||
etape = db.Column(db.String(APO_CODE_STR_LEN))
|
etape = db.Column(db.String(APO_CODE_STR_LEN))
|
||||||
# Parcours (pour les BUT)
|
# 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)
|
parcour = db.relationship(ApcParcours)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -51,11 +51,15 @@ class UniteEns(db.Model):
|
|||||||
color = db.Column(db.Text())
|
color = db.Column(db.Text())
|
||||||
|
|
||||||
# BUT
|
# 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")
|
niveau_competence = db.relationship("ApcNiveau", back_populates="ues")
|
||||||
|
|
||||||
# Une ue appartient soit à tous les parcours (tronc commun), soit à un seul:
|
# 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")
|
parcour = db.relationship("ApcParcours", back_populates="ues")
|
||||||
|
|
||||||
# relations
|
# relations
|
||||||
|
@ -160,11 +160,11 @@ class ScolarEvent(db.Model):
|
|||||||
event_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
event_date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
|
||||||
formsemestre_id = db.Column(
|
formsemestre_id = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("notes_formsemestre.id"),
|
db.ForeignKey("notes_formsemestre.id", ondelete="SET NULL"),
|
||||||
)
|
)
|
||||||
ue_id = db.Column(
|
ue_id = db.Column(
|
||||||
db.Integer,
|
db.Integer,
|
||||||
db.ForeignKey("notes_ue.id"),
|
db.ForeignKey("notes_ue.id", ondelete="SET NULL"),
|
||||||
)
|
)
|
||||||
# 'CREATION', 'INSCRIPTION', 'DEMISSION',
|
# 'CREATION', 'INSCRIPTION', 'DEMISSION',
|
||||||
# 'AUT_RED', 'EXCLUS', 'VALID_UE', 'VALID_SEM'
|
# 'AUT_RED', 'EXCLUS', 'VALID_UE', 'VALID_SEM'
|
||||||
|
@ -317,7 +317,7 @@ def _style_sems(sems):
|
|||||||
] = f""" data-oid="{sem['formsemestre_id']}" data-value="{sem['elt_sem_apo']}" """
|
] = 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"""
|
"""Suppression irréversible d'un département et de tous les objets rattachés"""
|
||||||
assert isinstance(dept_id, int)
|
assert isinstance(dept_id, int)
|
||||||
|
|
||||||
@ -361,6 +361,7 @@ def delete_dept(dept_id: int):
|
|||||||
)
|
)
|
||||||
|
|
||||||
reqs = [
|
reqs = [
|
||||||
|
"delete from apc_referentiel_competences where dept_id = %(dept_id)s",
|
||||||
"delete from identite 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 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_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:
|
for r in reqs:
|
||||||
cursor.execute(r, {"dept_id": dept_id})
|
cursor.execute(r, {"dept_id": dept_id})
|
||||||
except:
|
except Exception as e:
|
||||||
cnx.rollback()
|
cnx.rollback()
|
||||||
|
return str(e)
|
||||||
finally:
|
finally:
|
||||||
cnx.commit()
|
cnx.commit()
|
||||||
app.clear_scodoc_cache()
|
app.clear_scodoc_cache()
|
||||||
|
return ""
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
"""Dump base de données pour debug et support technique
|
"""Dump base de données pour debug et support technique
|
||||||
|
|
||||||
Le principe est le suivant:
|
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,
|
1- S'il existe une base en cours d'anonymisation, s'arrête et affiche un msg
|
||||||
qui peut décider de la supprimer.
|
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)
|
2- ScoDoc lance un script qui duplique la base (la copie de SCORT devient ANORT)
|
||||||
- (si elle existe deja, s'arrête)
|
- (si elle existe deja, s'arrête)
|
||||||
@ -49,9 +49,9 @@ pg_dump SCORT | psql ANORT
|
|||||||
import base64
|
import base64
|
||||||
import fcntl
|
import fcntl
|
||||||
import os
|
import os
|
||||||
import requests
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import traceback
|
|
||||||
|
import requests
|
||||||
|
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
from flask_login import current_user
|
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.notesdb as ndb
|
||||||
import app.scodoc.sco_utils as scu
|
import app.scodoc.sco_utils as scu
|
||||||
from app import log
|
from app import log
|
||||||
from app.scodoc import sco_users
|
|
||||||
import sco_version
|
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
import sco_version
|
||||||
|
|
||||||
SCO_DUMP_LOCK = "/tmp/scodump.lock"
|
SCO_DUMP_LOCK = "/tmp/scodump.lock"
|
||||||
|
|
||||||
@ -81,12 +80,10 @@ def sco_dump_and_send_db(
|
|||||||
try:
|
try:
|
||||||
x = open(SCO_DUMP_LOCK, "w+")
|
x = open(SCO_DUMP_LOCK, "w+")
|
||||||
fcntl.flock(x, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
fcntl.flock(x, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||||
except (IOError, OSError):
|
except (IOError, OSError) as e:
|
||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
"Un envoi de la base "
|
"Un envoi de la base {db_name} est déjà en cours, re-essayer plus tard"
|
||||||
+ db_name
|
) from e
|
||||||
+ " est déjà en cours, re-essayer plus tard"
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Drop if exists
|
# Drop if exists
|
||||||
@ -96,7 +93,7 @@ def sco_dump_and_send_db(
|
|||||||
_duplicate_db(db_name, ano_db_name)
|
_duplicate_db(db_name, ano_db_name)
|
||||||
|
|
||||||
# Anonymisation
|
# Anonymisation
|
||||||
_anonymize_db(ano_db_name)
|
anonymize_db(ano_db_name)
|
||||||
|
|
||||||
# Send
|
# Send
|
||||||
r = _send_db(ano_db_name, message, request_url, traceback_str=traceback_str)
|
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):
|
def _duplicate_db(db_name, ano_db_name):
|
||||||
"""Create new database, and copy old one into"""
|
"""Create new database, and copy old one into"""
|
||||||
cmd = ["createdb", "-E", "UTF-8", ano_db_name]
|
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:
|
try:
|
||||||
_ = subprocess.check_output(cmd)
|
_ = subprocess.check_output(cmd)
|
||||||
except subprocess.CalledProcessError as e:
|
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(
|
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))
|
log("sco_dump_and_send_db/_duplicate_db: {}".format(cmd))
|
||||||
try:
|
try:
|
||||||
_ = subprocess.check_output(cmd, shell=1)
|
_ = subprocess.check_output(cmd, shell=1)
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
log("sco_dump_and_send_db: exception {}".format(e))
|
log("sco_dump_and_send_db: exception {}".format(e))
|
||||||
raise ScoValueError(
|
raise ScoValueError(
|
||||||
"erreur lors de la duplication de la base {} vers {}".format(
|
f"erreur lors de la duplication de la base {db_name} vers {ano_db_name}"
|
||||||
db_name, ano_db_name
|
) from e
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _anonymize_db(ano_db_name):
|
def anonymize_db(ano_db_name):
|
||||||
"""Anonymize a departement database"""
|
"""Anonymize a ScoDoc database"""
|
||||||
cmd = os.path.join(scu.SCO_TOOLS_DIR, "anonymize_db.py")
|
cmd = os.path.join(scu.SCO_TOOLS_DIR, "anonymize_db.py")
|
||||||
log("_anonymize_db: {}".format(cmd))
|
log(f"anonymize_db: {cmd}")
|
||||||
try:
|
try:
|
||||||
_ = subprocess.check_output([cmd, ano_db_name])
|
_ = subprocess.check_output([cmd, ano_db_name])
|
||||||
except subprocess.CalledProcessError as e:
|
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(
|
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():
|
def _get_scodoc_serial():
|
||||||
try:
|
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())
|
return int(f.read())
|
||||||
except:
|
except:
|
||||||
return 0
|
return 0
|
||||||
|
415
migrations/versions/d8288b7f0a3e_cascades_ref_comp.py
Normal file
415
migrations/versions/d8288b7f0a3e_cascades_ref_comp.py
Normal 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 ###
|
19
scodoc.py
19
scodoc.py
@ -41,6 +41,7 @@ from app.models.but_refcomp import (
|
|||||||
)
|
)
|
||||||
from app.models.but_validations import ApcValidationAnnee, ApcValidationRCUE
|
from app.models.but_validations import ApcValidationAnnee, ApcValidationRCUE
|
||||||
from app.models.evaluations import Evaluation
|
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_logos import make_logo_local
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.views import notes, scolar
|
from app.views import notes, scolar
|
||||||
@ -131,6 +132,18 @@ def sco_db_init(erase=False): # sco-db-init
|
|||||||
initialize_scodoc_database(erase=erase)
|
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()
|
@app.cli.command()
|
||||||
def user_db_clear():
|
def user_db_clear():
|
||||||
"""Erase all users and roles from the database !"""
|
"""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")
|
sys.stderr.write(f"Erreur: le departement {dept} n'existe pas !\n")
|
||||||
return 2
|
return 2
|
||||||
elif d:
|
elif d:
|
||||||
sco_dept.delete_dept(d.id)
|
msg = sco_dept.delete_dept(d.id)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return 0
|
if msg:
|
||||||
|
print(f"Erreur:\n {msg}")
|
||||||
|
return 0 if not msg else 1
|
||||||
|
|
||||||
|
|
||||||
@app.cli.command()
|
@app.cli.command()
|
||||||
|
@ -26,8 +26,6 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# TODO à tester avec ScoDoc9, devrait fonctionner sans problème majeur ?
|
|
||||||
|
|
||||||
"""Anonymize une base de données ScoDoc
|
"""Anonymize une base de données ScoDoc
|
||||||
|
|
||||||
Runned as user "scodoc" with scodoc and postgresql up.
|
Runned as user "scodoc" with scodoc and postgresql up.
|
||||||
|
Loading…
Reference in New Issue
Block a user