forked from ScoDoc/ScoDoc
Fix: déclaration table Identite / Unicite codes
This commit is contained in:
parent
e745a7938e
commit
b5b606b1f6
@ -27,6 +27,7 @@ class Identite(db.Model):
|
|||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
db.UniqueConstraint("dept_id", "code_nip"),
|
db.UniqueConstraint("dept_id", "code_nip"),
|
||||||
db.UniqueConstraint("dept_id", "code_ine"),
|
db.UniqueConstraint("dept_id", "code_ine"),
|
||||||
|
db.CheckConstraint("civilite IN ('M', 'F', 'X')"),
|
||||||
)
|
)
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
@ -36,10 +37,8 @@ class Identite(db.Model):
|
|||||||
nom = db.Column(db.Text())
|
nom = db.Column(db.Text())
|
||||||
prenom = db.Column(db.Text())
|
prenom = db.Column(db.Text())
|
||||||
nom_usuel = db.Column(db.Text())
|
nom_usuel = db.Column(db.Text())
|
||||||
# optionnel (si present, affiché à la place du nom)
|
"optionnel (si present, affiché à la place du nom)"
|
||||||
civilite = db.Column(db.String(1), nullable=False)
|
civilite = db.Column(db.String(1), nullable=False)
|
||||||
__table_args__ = (db.CheckConstraint("civilite IN ('M', 'F', 'X')"),)
|
|
||||||
|
|
||||||
date_naissance = db.Column(db.Date)
|
date_naissance = db.Column(db.Date)
|
||||||
lieu_naissance = db.Column(db.Text())
|
lieu_naissance = db.Column(db.Text())
|
||||||
dept_naissance = db.Column(db.Text())
|
dept_naissance = db.Column(db.Text())
|
||||||
|
@ -301,24 +301,27 @@ def check_nom_prenom(cnx, nom="", prenom="", etudid=None):
|
|||||||
|
|
||||||
|
|
||||||
def _check_duplicate_code(cnx, args, code_name, disable_notify=False, edit=True):
|
def _check_duplicate_code(cnx, args, code_name, disable_notify=False, edit=True):
|
||||||
|
"""Vérifie que le code n'est pas dupliqué"""
|
||||||
etudid = args.get("etudid", None)
|
etudid = args.get("etudid", None)
|
||||||
if args.get(code_name, None):
|
if args.get(code_name, None):
|
||||||
etuds = identite_list(cnx, {code_name: str(args[code_name])})
|
etuds = identite_list(cnx, {code_name: str(args[code_name])})
|
||||||
# log('etuds=%s'%etuds)
|
duplicate = False
|
||||||
nb_max = 0
|
|
||||||
if edit:
|
if edit:
|
||||||
nb_max = 1
|
duplicate = (len(etuds) > 1) or (
|
||||||
if len(etuds) > nb_max:
|
(len(etuds) == 1) and etuds[0]["id"] != args["etudid"]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
duplicate = len(etuds) > 0
|
||||||
|
if duplicate:
|
||||||
listh = [] # liste des doubles
|
listh = [] # liste des doubles
|
||||||
for e in etuds:
|
for e in etuds:
|
||||||
listh.append(
|
listh.append(
|
||||||
"""Autre étudiant: <a href="%s">"""
|
f"""Autre étudiant: <a href="{
|
||||||
% url_for(
|
url_for(
|
||||||
"scolar.ficheEtud",
|
"scolar.ficheEtud",
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
etudid=e["etudid"],
|
etudid=e["etudid"]
|
||||||
)
|
)}">{e['nom']} {e['prenom']}</a>"""
|
||||||
+ """%(nom)s %(prenom)s</a>""" % e
|
|
||||||
)
|
)
|
||||||
if etudid:
|
if etudid:
|
||||||
OK = "retour à la fiche étudiant"
|
OK = "retour à la fiche étudiant"
|
||||||
@ -349,7 +352,7 @@ def _check_duplicate_code(cnx, args, code_name, disable_notify=False, edit=True)
|
|||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
err_page = f"""<h3>Code étudiant ({code_name}) dupliqué !</h3>"""
|
err_page = f"""<h3>Code étudiant ({code_name}) dupliqué !</h3>"""
|
||||||
log("*** error: code %s duplique: %s" % (code_name, args[code_name]))
|
log(f"*** error: code {code_name} duplique: {args[code_name]}")
|
||||||
raise ScoGenError(err_page)
|
raise ScoGenError(err_page)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1732,7 +1732,9 @@ def _etudident_create_or_edit_form(edit):
|
|||||||
formsemestre_id=formsemestre_id
|
formsemestre_id=formsemestre_id
|
||||||
) # > etudident_create_or_edit
|
) # > etudident_create_or_edit
|
||||||
#
|
#
|
||||||
return flask.redirect("ficheEtud?etudid=" + str(etudid))
|
return flask.redirect(
|
||||||
|
url_for("scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/etudident_delete", methods=["GET", "POST"])
|
@bp.route("/etudident_delete", methods=["GET", "POST"])
|
||||||
|
97
migrations/versions/ae9bb0feea7a_contraintes_identite.py
Normal file
97
migrations/versions/ae9bb0feea7a_contraintes_identite.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
"""contraintes identite
|
||||||
|
|
||||||
|
Revision ID: ae9bb0feea7a
|
||||||
|
Revises: 5731e904baac
|
||||||
|
Create Date: 2023-03-12 19:00:58.544873
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.orm import sessionmaker # added by ev
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = "ae9bb0feea7a"
|
||||||
|
down_revision = "5731e904baac"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
Session = sessionmaker()
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# On répare une erreur (typo) dans la déclaration de la table Identite
|
||||||
|
# qui faisait que les contraintes d'unicité des couples (ine, dept)
|
||||||
|
# et (nip, dept) n'était pas prises en compte.
|
||||||
|
# On commence par chercher les éventuels (rares) doublons, changer leurs codes
|
||||||
|
# avant de créer les contraintes.
|
||||||
|
bind = op.get_bind()
|
||||||
|
session = Session(bind=bind)
|
||||||
|
# Corrige NIP
|
||||||
|
dups = session.execute(
|
||||||
|
"""SELECT dept_id, code_nip
|
||||||
|
FROM identite
|
||||||
|
WHERE code_nip IS NOT NULL
|
||||||
|
GROUP BY dept_id, code_nip
|
||||||
|
HAVING COUNT(*) > 1;"""
|
||||||
|
).all()
|
||||||
|
for dept_id, code_nip in dups:
|
||||||
|
etuds_dups = session.execute(
|
||||||
|
"""SELECT id, nom, prenom FROM identite
|
||||||
|
WHERE code_nip=:code_nip""",
|
||||||
|
{"code_nip": code_nip},
|
||||||
|
).all()
|
||||||
|
for i, (etudid, nom, prenom) in enumerate(etuds_dups[1:], start=1):
|
||||||
|
session.execute(
|
||||||
|
"""UPDATE identite SET code_nip=:code_nip WHERE id=:etudid""",
|
||||||
|
{
|
||||||
|
"code_nip": f"{code_nip}-{i}",
|
||||||
|
"etudid": etudid,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f"Warning: duplication de code NIP détectée: vérifier {nom} {prenom} NIP={code_nip}"
|
||||||
|
)
|
||||||
|
session.commit()
|
||||||
|
# Corrige INE
|
||||||
|
dups = session.execute(
|
||||||
|
"""SELECT dept_id, code_ine
|
||||||
|
FROM identite
|
||||||
|
WHERE code_ine IS NOT NULL
|
||||||
|
GROUP BY dept_id, code_ine
|
||||||
|
HAVING COUNT(*) > 1;"""
|
||||||
|
).all()
|
||||||
|
for dept_id, code_ine in dups:
|
||||||
|
etuds_dups = session.execute(
|
||||||
|
"""SELECT id, nom, prenom FROM identite
|
||||||
|
WHERE code_ine=:code_ine""",
|
||||||
|
{"code_ine": code_ine},
|
||||||
|
).all()
|
||||||
|
for i, (etudid, nom, prenom) in enumerate(etuds_dups[1:], start=1):
|
||||||
|
session.execute(
|
||||||
|
"""UPDATE identite SET code_ine=:code_ine WHERE id=:etudid""",
|
||||||
|
{
|
||||||
|
"code_ine": f"{code_ine}-{i}",
|
||||||
|
"etudid": etudid,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f"Warning: duplication de code INE détectée: vérifier {nom} {prenom} NIP={code_ine}"
|
||||||
|
)
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
# CREATION DES CONTRAINTES
|
||||||
|
op.create_unique_constraint(
|
||||||
|
"identite_dept_id_code_nip_key", "identite", ["dept_id", "code_nip"]
|
||||||
|
)
|
||||||
|
op.create_unique_constraint(
|
||||||
|
"identite_dept_id_code_ine_key", "identite", ["dept_id", "code_ine"]
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_constraint("identite_dept_id_code_nip_key", "identite", type_="unique")
|
||||||
|
op.drop_constraint("identite_dept_id_code_ine_key", "identite", type_="unique")
|
||||||
|
# ### end Alembic commands ###
|
Loading…
Reference in New Issue
Block a user