"""Change ApcValidationAnnee Revision ID: 829683efddc4 Revises: c701224fa255 Create Date: 2023-06-28 09:47:16.591028 """ from alembic import op import sqlalchemy as sa from sqlalchemy.orm import sessionmaker # added by ev # revision identifiers, used by Alembic. revision = "829683efddc4" down_revision = "c701224fa255" branch_labels = None depends_on = None Session = sessionmaker() # Voir https://stackoverflow.com/questions/24082542/check-if-a-table-column-exists-in-the-database-using-sqlalchemy-and-alembic from sqlalchemy import inspect def column_exists(table_name, column_name): bind = op.get_context().bind insp = inspect(bind) columns = insp.get_columns(table_name) return any(c["name"] == column_name for c in columns) def upgrade(): if column_exists("apc_validation_annee", "referentiel_competence_id"): return # utile durant developpement # Enleve la contrainte erronée with op.batch_alter_table("apc_validation_annee", schema=None) as batch_op: batch_op.drop_constraint( "apc_validation_annee_etudid_annee_scolaire_ordre_key", type_="unique" ) # Ajoute colonne referentiel, nullable pour l'instant batch_op.add_column( sa.Column("referentiel_competence_id", sa.Integer(), nullable=True) ) # Affecte le referentiel des anciennes validations bind = op.get_bind() session = Session(bind=bind) session.execute( sa.text( """ UPDATE apc_validation_annee AS a SET referentiel_competence_id = ( SELECT f.referentiel_competence_id FROM notes_formations f WHERE f.id = a.formation_id ) """ ) ) # En principe, on n'a pas pu entrer de validation sur des formations sans referentiel # par prudence, on les supprime avant d'ajouter la contrainte session.execute( sa.text( "DELETE FROM apc_validation_annee WHERE referentiel_competence_id is NULL" ) ) op.alter_column( "apc_validation_annee", "referentiel_competence_id", nullable=False, ) op.create_foreign_key( "apc_validation_annee_refcomp_fkey", "apc_validation_annee", "apc_referentiel_competences", ["referentiel_competence_id"], ["id"], ) # Efface les validations d'année dupliquées # (garde la validation la plus récente) session.execute( sa.text( """ DELETE FROM apc_validation_annee t1 WHERE t1.id <> (SELECT max(t2.id) FROM apc_validation_annee t2 WHERE t1.etudid = t2.etudid AND t1.referentiel_competence_id = t2.referentiel_competence_id AND t1.ordre = t2.ordre ) """ ) ) # Et ajoute la contrainte unicité de décision année par étudiant/ref. comp.: op.create_unique_constraint( "apc_validation_annee_etudid_ordre_refcomp_key", "apc_validation_annee", ["etudid", "ordre", "referentiel_competence_id"], ) op.drop_column("apc_validation_annee", "formation_id") def downgrade(): # Se contente de ré-ajouter la colonne formation_id sans re-générer son contenu with op.batch_alter_table("apc_validation_annee", schema=None) as batch_op: # batch_op.drop_constraint( # "apc_validation_annee_etudid_ordre_refcomp_key", type_="unique" # ) # batch_op.drop_column("referentiel_competence_id") batch_op.add_column(sa.Column("formation_id", sa.Integer(), nullable=True))