Compare commits

...

26 Commits

Author SHA1 Message Date
2908f94b4a Ajout d'un paramètre de tour pour importer des données 2024-07-19 22:10:20 +02:00
645951823a Ajout données T2 législatives 2024 2024-07-19 22:01:01 +02:00
47cfdf705a Correction Exprimés 2024-07-07 13:35:11 +02:00
600aa8d5c1 On ignore les communes non trouvées (pour le moment) 2024-07-07 09:10:16 +02:00
205f8a5c84 Correction import voix exprimées 2024-07-02 22:18:08 +02:00
313b161a06 Correction import bureau de vote 2024-07-02 21:54:02 +02:00
47641924df Correction code commune 2024-07-02 17:14:28 +02:00
9543df0d8d Importation des résultats des législatives 2024 2024-07-02 14:43:48 +02:00
b514a61d72 Importation du script d'exportation des résultats 2024-06-28 13:45:56 +02:00
22ebabda99 Visualisation résultats législatives 2024 2024-06-28 13:42:37 +02:00
b4d6885631 Script export données législatives 2024 2024-06-28 13:40:57 +02:00
0b0508958c On affiche pas les résultats du second tour s'il n'y en a pas 2024-06-28 13:39:38 +02:00
d78ac420d8 Accélération import résultats bureaux vote 2024-06-21 11:06:00 +02:00
afc1d3f85f Correction import résultats bureaux de vote tour 2 2024-06-21 10:49:05 +02:00
8b45bc81ad Correction affichage personne élue 2024-06-21 00:24:07 +02:00
0fef97dd82 Meilleur affichage participation tour 1 + 2 2024-06-21 00:14:19 +02:00
d75ab4d0f3 Commit des imports de bureau de vote par bureau de vote 2024-06-20 23:32:19 +02:00
5f279fa949 Affichage élections législatives 2022 2024-06-20 23:29:18 +02:00
1b0b894acc Correction import résultats bureau de vote législatives 2022 2024-06-20 21:00:37 +02:00
3d60013670 Séparation des résultats par tour 2024-06-20 18:36:52 +02:00
63e2366837 Correction enumérations 2024-06-20 16:55:16 +02:00
782320652e Correction enumérations 2024-06-20 16:48:34 +02:00
ada3941d44 Import candidat⋅es législatives 2024 2024-06-20 16:43:42 +02:00
df8c8db32d Export données législatives 2024 2024-06-20 16:05:24 +02:00
7aa92d28d4 Import résultats législatives 2024-06-20 14:45:53 +02:00
8f8028028e Début import législatives 2022 2024-06-20 12:17:56 +02:00
27 changed files with 4738 additions and 267 deletions

View File

@ -110,10 +110,10 @@ def upgrade() -> None:
sa.Column('ordre', sa.Integer(), nullable=False), sa.Column('ordre', sa.Integer(), nullable=False),
sa.Column('nom', sa.String(length=256), nullable=False), sa.Column('nom', sa.String(length=256), nullable=False),
sa.Column('prenom', sa.String(length=256), nullable=False), sa.Column('prenom', sa.String(length=256), nullable=False),
sa.Column('sexe', sa.Enum('MASCULIN', 'FEMININ', name='genre'), nullable=False), sa.Column('sexe', sa.Enum('MASCULIN', 'FEMININ', name='europeennes_2024_genre'), nullable=False),
sa.Column('date_naissance', sa.Date(), nullable=False), sa.Column('date_naissance', sa.Date(), nullable=False),
sa.Column('profession', sa.String(length=256), nullable=False), sa.Column('profession', sa.String(length=256), nullable=False),
sa.Column('code_personnalite', sa.Enum('DEFAUT', 'EURODEPUTE', 'DEPUTE', 'SENATEUR', 'MINISTRE', 'PRESIDENT_CONSEIL_REGIONAL', 'PRESIDENT_CONSEIL_DEPARTEMENTAL', 'MAIRE', name='personnalite'), nullable=False), sa.Column('code_personnalite', sa.Enum('DEFAUT', 'EURODEPUTE', 'DEPUTE', 'SENATEUR', 'MINISTRE', 'PRESIDENT_CONSEIL_REGIONAL', 'PRESIDENT_CONSEIL_DEPARTEMENTAL', 'MAIRE', name='europeennes_2024_personnalite'), nullable=False),
sa.Column('sortant', sa.Boolean(), nullable=False), sa.Column('sortant', sa.Boolean(), nullable=False),
sa.ForeignKeyConstraint(['liste_id'], ['europeennes_2024_liste.id'], ), sa.ForeignKeyConstraint(['liste_id'], ['europeennes_2024_liste.id'], ),
sa.PrimaryKeyConstraint('id') sa.PrimaryKeyConstraint('id')

View File

@ -0,0 +1,490 @@
"""ajout modèles législatives 2022 + 2024
Revision ID: d6a8883dd958
Revises: c0443e979a90
Create Date: 2024-06-20 16:54:24.042835
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'd6a8883dd958'
down_revision: Union[str, None] = 'c0443e979a90'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('legislatives_2022_bloc',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nom', sa.String(length=32), nullable=False),
sa.Column('couleur', sa.String(length=7), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('nom')
)
op.create_table('legislatives_2022_resultats_france',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_bloc',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nom', sa.String(length=32), nullable=False),
sa.Column('couleur', sa.String(length=7), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('nom')
)
op.create_table('legislatives_2024_resultats_france',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_nuance',
sa.Column('code', sa.String(length=8), nullable=False),
sa.Column('nom', sa.String(length=64), nullable=False),
sa.Column('couleur', sa.String(length=7), nullable=False),
sa.Column('bloc_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['bloc_id'], ['legislatives_2022_bloc.id'], ),
sa.PrimaryKeyConstraint('code'),
sa.UniqueConstraint('nom')
)
op.create_table('legislatives_2022_resultats_region',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('region_id', sa.String(length=3), nullable=False),
sa.Column('resultats_france_id', sa.Integer(), nullable=False),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['region_id'], ['region.code_insee'], ),
sa.ForeignKeyConstraint(['resultats_france_id'], ['legislatives_2022_resultats_france.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_nuance',
sa.Column('code', sa.String(length=8), nullable=False),
sa.Column('nom', sa.String(length=64), nullable=False),
sa.Column('couleur', sa.String(length=7), nullable=False),
sa.Column('bloc_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['bloc_id'], ['legislatives_2024_bloc.id'], ),
sa.PrimaryKeyConstraint('code'),
sa.UniqueConstraint('nom')
)
op.create_table('legislatives_2024_resultats_region',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('region_id', sa.String(length=3), nullable=False),
sa.Column('resultats_france_id', sa.Integer(), nullable=False),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['region_id'], ['region.code_insee'], ),
sa.ForeignKeyConstraint(['resultats_france_id'], ['legislatives_2024_resultats_france.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_resultats_departement',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('dpt_id', sa.String(length=3), nullable=False),
sa.Column('resultats_region_id', sa.Integer(), nullable=True),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['dpt_id'], ['departement.code_insee'], ),
sa.ForeignKeyConstraint(['resultats_region_id'], ['legislatives_2022_resultats_region.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_voix_france',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('resultats_france_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2022_nuance.code'], ),
sa.ForeignKeyConstraint(['resultats_france_id'], ['legislatives_2022_resultats_france.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_voix_region',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('resultats_region_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2022_nuance.code'], ),
sa.ForeignKeyConstraint(['resultats_region_id'], ['legislatives_2022_resultats_region.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_resultats_departement',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('dpt_id', sa.String(length=3), nullable=False),
sa.Column('resultats_region_id', sa.Integer(), nullable=True),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['dpt_id'], ['departement.code_insee'], ),
sa.ForeignKeyConstraint(['resultats_region_id'], ['legislatives_2024_resultats_region.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_voix_france',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('resultats_france_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2024_nuance.code'], ),
sa.ForeignKeyConstraint(['resultats_france_id'], ['legislatives_2024_resultats_france.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_voix_region',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('resultats_region_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2024_nuance.code'], ),
sa.ForeignKeyConstraint(['resultats_region_id'], ['legislatives_2024_resultats_region.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_candidat',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('circonscription_id', sa.String(length=6), nullable=False),
sa.Column('numero', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('bloc_id', sa.Integer(), nullable=False),
sa.Column('nom', sa.String(length=256), nullable=False),
sa.Column('prenom', sa.String(length=256), nullable=False),
sa.Column('sexe', sa.Enum('MASCULIN', 'FEMININ', name='legislatives_2022_genre'), nullable=False),
sa.Column('date_naissance', sa.Date(), nullable=False),
sa.Column('profession', sa.String(length=256), nullable=False),
sa.Column('sortant', sa.Boolean(), nullable=False),
sa.Column('nom_suppleance', sa.String(length=256), nullable=False),
sa.Column('prenom_suppleance', sa.String(length=256), nullable=False),
sa.Column('sexe_suppleance', sa.Enum('MASCULIN', 'FEMININ', name='legislatives_2022_genre'), nullable=False),
sa.Column('date_naissance_suppleance', sa.Date(), nullable=False),
sa.Column('sortant_suppleance', sa.Boolean(), nullable=False),
sa.ForeignKeyConstraint(['bloc_id'], ['legislatives_2022_bloc.id'], ),
sa.ForeignKeyConstraint(['circonscription_id'], ['circonscription.id'], ),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2022_nuance.code'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_resultats_circonscription',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('circo_id', sa.String(length=6), nullable=False),
sa.Column('resultats_departement_id', sa.Integer(), nullable=False),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['circo_id'], ['circonscription.id'], ),
sa.ForeignKeyConstraint(['resultats_departement_id'], ['legislatives_2022_resultats_departement.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_resultats_commune',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('commune_id', sa.String(length=5), nullable=False),
sa.Column('resultats_dpt_id', sa.Integer(), nullable=False),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['commune_id'], ['commune.code_insee'], ),
sa.ForeignKeyConstraint(['resultats_dpt_id'], ['legislatives_2022_resultats_departement.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_voix_departement',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('resultats_departement_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2022_nuance.code'], ),
sa.ForeignKeyConstraint(['resultats_departement_id'], ['legislatives_2022_resultats_departement.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_candidat',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('circonscription_id', sa.String(length=6), nullable=False),
sa.Column('numero', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('bloc_id', sa.Integer(), nullable=False),
sa.Column('nom', sa.String(length=256), nullable=False),
sa.Column('prenom', sa.String(length=256), nullable=False),
sa.Column('sexe', sa.Enum('MASCULIN', 'FEMININ', name='legislatives_2024_genre'), nullable=False),
sa.Column('date_naissance', sa.Date(), nullable=False),
sa.Column('profession', sa.String(length=256), nullable=False),
sa.Column('sortant', sa.Boolean(), nullable=False),
sa.Column('nom_suppleance', sa.String(length=256), nullable=False),
sa.Column('prenom_suppleance', sa.String(length=256), nullable=False),
sa.Column('sexe_suppleance', sa.Enum('MASCULIN', 'FEMININ', name='legislatives_2024_genre_suppl'), nullable=False),
sa.Column('date_naissance_suppleance', sa.Date(), nullable=False),
sa.Column('sortant_suppleance', sa.Boolean(), nullable=False),
sa.ForeignKeyConstraint(['bloc_id'], ['legislatives_2024_bloc.id'], ),
sa.ForeignKeyConstraint(['circonscription_id'], ['circonscription.id'], ),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2024_nuance.code'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_resultats_circonscription',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('circo_id', sa.String(length=6), nullable=False),
sa.Column('resultats_departement_id', sa.Integer(), nullable=False),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['circo_id'], ['circonscription.id'], ),
sa.ForeignKeyConstraint(['resultats_departement_id'], ['legislatives_2024_resultats_departement.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_resultats_commune',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('commune_id', sa.String(length=5), nullable=False),
sa.Column('resultats_dpt_id', sa.Integer(), nullable=False),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['commune_id'], ['commune.code_insee'], ),
sa.ForeignKeyConstraint(['resultats_dpt_id'], ['legislatives_2024_resultats_departement.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_voix_departement',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('resultats_departement_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2024_nuance.code'], ),
sa.ForeignKeyConstraint(['resultats_departement_id'], ['legislatives_2024_resultats_departement.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_resultats_bureau_vote',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('bv_id', sa.String(length=16), nullable=False),
sa.Column('resultats_commune_id', sa.Integer(), nullable=False),
sa.Column('resultats_circo_id', sa.Integer(), nullable=True),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['bv_id'], ['bureau_vote.id'], ),
sa.ForeignKeyConstraint(['resultats_circo_id'], ['legislatives_2022_resultats_circonscription.id'], ),
sa.ForeignKeyConstraint(['resultats_commune_id'], ['legislatives_2022_resultats_commune.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_voix_circonscription',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('candidat_id', sa.Integer(), nullable=False),
sa.Column('resultats_circonscription_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['candidat_id'], ['legislatives_2022_candidat.id'], ),
sa.ForeignKeyConstraint(['resultats_circonscription_id'], ['legislatives_2022_resultats_circonscription.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_voix_commune',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('resultats_commune_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2022_nuance.code'], ),
sa.ForeignKeyConstraint(['resultats_commune_id'], ['legislatives_2022_resultats_commune.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_resultats_bureau_vote',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('bv_id', sa.String(length=16), nullable=False),
sa.Column('resultats_commune_id', sa.Integer(), nullable=False),
sa.Column('resultats_circo_id', sa.Integer(), nullable=True),
sa.Column('inscrits_t1', sa.Integer(), nullable=False),
sa.Column('votants_t1', sa.Integer(), nullable=False),
sa.Column('abstentions_t1', sa.Integer(), nullable=False),
sa.Column('exprimes_t1', sa.Integer(), nullable=False),
sa.Column('blancs_t1', sa.Integer(), nullable=False),
sa.Column('nuls_t1', sa.Integer(), nullable=False),
sa.Column('inscrits_t2', sa.Integer(), nullable=False),
sa.Column('votants_t2', sa.Integer(), nullable=False),
sa.Column('abstentions_t2', sa.Integer(), nullable=False),
sa.Column('exprimes_t2', sa.Integer(), nullable=False),
sa.Column('blancs_t2', sa.Integer(), nullable=False),
sa.Column('nuls_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['bv_id'], ['bureau_vote.id'], ),
sa.ForeignKeyConstraint(['resultats_circo_id'], ['legislatives_2024_resultats_circonscription.id'], ),
sa.ForeignKeyConstraint(['resultats_commune_id'], ['legislatives_2024_resultats_commune.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_voix_circonscription',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('candidat_id', sa.Integer(), nullable=False),
sa.Column('resultats_circonscription_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['candidat_id'], ['legislatives_2024_candidat.id'], ),
sa.ForeignKeyConstraint(['resultats_circonscription_id'], ['legislatives_2024_resultats_circonscription.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_voix_commune',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('nuance_id', sa.String(length=8), nullable=False),
sa.Column('resultats_commune_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['nuance_id'], ['legislatives_2024_nuance.code'], ),
sa.ForeignKeyConstraint(['resultats_commune_id'], ['legislatives_2024_resultats_commune.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2022_voix_bureau_vote',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('candidat_id', sa.Integer(), nullable=False),
sa.Column('resultats_bureau_vote_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['candidat_id'], ['legislatives_2022_candidat.id'], ),
sa.ForeignKeyConstraint(['resultats_bureau_vote_id'], ['legislatives_2022_resultats_bureau_vote.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_table('legislatives_2024_voix_bureau_vote',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('candidat_id', sa.Integer(), nullable=False),
sa.Column('resultats_bureau_vote_id', sa.Integer(), nullable=False),
sa.Column('voix_t1', sa.Integer(), nullable=False),
sa.Column('voix_t2', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['candidat_id'], ['legislatives_2024_candidat.id'], ),
sa.ForeignKeyConstraint(['resultats_bureau_vote_id'], ['legislatives_2024_resultats_bureau_vote.id'], ),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('legislatives_2024_voix_bureau_vote')
op.drop_table('legislatives_2022_voix_bureau_vote')
op.drop_table('legislatives_2024_voix_commune')
op.drop_table('legislatives_2024_voix_circonscription')
op.drop_table('legislatives_2024_resultats_bureau_vote')
op.drop_table('legislatives_2022_voix_commune')
op.drop_table('legislatives_2022_voix_circonscription')
op.drop_table('legislatives_2022_resultats_bureau_vote')
op.drop_table('legislatives_2024_voix_departement')
op.drop_table('legislatives_2024_resultats_commune')
op.drop_table('legislatives_2024_resultats_circonscription')
op.drop_table('legislatives_2024_candidat')
op.drop_table('legislatives_2022_voix_departement')
op.drop_table('legislatives_2022_resultats_commune')
op.drop_table('legislatives_2022_resultats_circonscription')
op.drop_table('legislatives_2022_candidat')
op.drop_table('legislatives_2024_voix_region')
op.drop_table('legislatives_2024_voix_france')
op.drop_table('legislatives_2024_resultats_departement')
op.drop_table('legislatives_2022_voix_region')
op.drop_table('legislatives_2022_voix_france')
op.drop_table('legislatives_2022_resultats_departement')
op.drop_table('legislatives_2024_resultats_region')
op.drop_table('legislatives_2024_nuance')
op.drop_table('legislatives_2022_resultats_region')
op.drop_table('legislatives_2022_nuance')
op.drop_table('legislatives_2024_resultats_france')
op.drop_table('legislatives_2024_bloc')
op.drop_table('legislatives_2022_resultats_france')
op.drop_table('legislatives_2022_bloc')
# ### end Alembic commands ###

17
main.py
View File

@ -7,15 +7,19 @@ from dotenv import load_dotenv
from sqlalchemy import create_engine from sqlalchemy import create_engine
from nupes.scripts import import_geographie from nupes.scripts import import_geographie
from nupes.scripts import europeennes2024 from nupes.scripts import legislatives2022, europeennes2024, legislatives2024
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description="Gestion d'élections") parser = argparse.ArgumentParser(description="Gestion d'élections")
parser.add_argument('--type', '-t', type=str, help="Type d'élection", parser.add_argument('--type', '-t', type=str, help="Type d'élection",
choices=["présidentielle", "législatives", "sénatoriales", "européennes", choices=["présidentielle", "législatives", "sénatoriales", "européennes",
"régionales", "départementales", "municipales"], default="européennes") "régionales", "départementales", "municipales"], default="législatives")
parser.add_argument('--year', '-y', type=int, help="Année de l'élection", default=2024) parser.add_argument('--year', '-y', type=int, help="Année de l'élection",
choices=[2022, 2024], default=2024)
parser.add_argument('--round', '-r', type=int,
help="Tour de l'élection à importer (0 pour tous, valeur par défaut)",
choices=[0, 1, 2], default=0)
parser.add_argument('action', help="Action à réaliser", parser.add_argument('action', help="Action à réaliser",
choices=["import_candidats", "import_geographie", "import_resultats", choices=["import_candidats", "import_geographie", "import_resultats",
"import_resultats_web", "export_resultats"]) "import_resultats_web", "export_resultats"])
@ -29,12 +33,17 @@ def main():
load_dotenv() load_dotenv()
args = parse_args() args = parse_args()
data_round = args.round
debug = args.debug debug = args.debug
verbose = args.verbose verbose = args.verbose
match args.type, args.year: match args.type, args.year:
case "législatives", 2022:
election_module = legislatives2022
case "européennes", 2024: case "européennes", 2024:
election_module = europeennes2024 election_module = europeennes2024
case "législatives", 2024:
election_module = legislatives2024
case _: case _:
print(f"Type d'élection {args.type} {args.year} non reconnu") print(f"Type d'élection {args.type} {args.year} non reconnu")
return return
@ -53,7 +62,7 @@ def main():
case "import_resultats": case "import_resultats":
if verbose: if verbose:
print(f"Import des résultats pour les élections {args.type} {args.year}") print(f"Import des résultats pour les élections {args.type} {args.year}")
election_module.import_resultats.run(engine, verbose) election_module.import_resultats.run(engine, data_round, verbose)
case "import_resultats_web": case "import_resultats_web":
if verbose: if verbose:
print(f"Import des résultats depuis le web pour les élections {args.type} {args.year}") print(f"Import des résultats depuis le web pour les élections {args.type} {args.year}")

View File

@ -1,21 +1,39 @@
import {createBrowserRouter, RouterProvider} from "react-router-dom" import {createBrowserRouter, RouterProvider} from "react-router-dom"
import './App.css' import './App.css'
import Elections2024 from './Elections2024' import ElectionsLegislatives2022 from './ElectionsLegislatives2022'
import ElectionsEuropeennes2024 from './ElectionsEuropeennes2024'
import ElectionsLegislatives2024 from './ElectionsLegislatives2024'
function App() { function App() {
const router = createBrowserRouter([ const router = createBrowserRouter([
{ {
path: "/", path: "/",
element: <Elections2024 typeResultats="france" />, element: <ElectionsEuropeennes2024 typeResultats="france" />,
},
{
path: "/elections/legislatives/2022/:typeResultats/",
element: <ElectionsLegislatives2022 />,
},
{
path: "/elections/legislatives/2022/:typeResultats/:zoneId/",
element: <ElectionsLegislatives2022 />
}, },
{ {
path: "/elections/europeennes/2024/:typeResultats/", path: "/elections/europeennes/2024/:typeResultats/",
element: <Elections2024 />, element: <ElectionsEuropeennes2024 />,
}, },
{ {
path: "/elections/europeennes/2024/:typeResultats/:zoneId/", path: "/elections/europeennes/2024/:typeResultats/:zoneId/",
element: <Elections2024 /> element: <ElectionsEuropeennes2024 />
},
{
path: "/elections/legislatives/2024/:typeResultats/",
element: <ElectionsLegislatives2024 />,
},
{
path: "/elections/legislatives/2024/:typeResultats/:zoneId/",
element: <ElectionsLegislatives2024 />
}, },
]) ])

View File

@ -16,7 +16,7 @@ import 'leaflet/dist/leaflet.css'
highchartsItem(Highcharts) highchartsItem(Highcharts)
export default function Election2024() { export default function ElectionsEuropeennes2024() {
const {typeResultats, zoneId} = useParams() const {typeResultats, zoneId} = useParams()
const [grouperParBloc, setGrouperParBloc] = useState(false) const [grouperParBloc, setGrouperParBloc] = useState(false)
@ -25,7 +25,8 @@ export default function Election2024() {
const [nuances, setNuances] = useState([]) const [nuances, setNuances] = useState([])
const [listes, setListes] = useState([]) const [listes, setListes] = useState([])
const [resultats, setResultats] = useState([]) const [resultats, setResultats] = useState([])
const [typeZone, setTypeZone] = useState("region") const [typeSousZone, setTypeSousZone] = useState("region")
const tour = 1
useEffect(() => { useEffect(() => {
fetch("/data/resultats/europeennes/2024/blocs.json").then(response => response.json()) fetch("/data/resultats/europeennes/2024/blocs.json").then(response => response.json())
@ -46,35 +47,63 @@ export default function Election2024() {
} }
}, [typeResultats, zoneId]) }, [typeResultats, zoneId])
const nomZone = useMemo(() => getNomZone(typeResultats, resultats), const zoneInfo = useMemo(() => resultats?.zone ?? {}, [resultats])
[typeResultats, resultats]) const nomZone = useMemo(() => getNomZone(typeResultats, zoneInfo), [typeResultats, zoneInfo])
const [voixParBloc, voixParNuance] = regrouperVoix(resultats.voix, listes, blocs, nuances) const donnees = useMemo(() => {
if (tour === 1)
return resultats?.tour1 ?? {}
else if (tour === 2)
return resultats?.tour2 ?? {}
else
return {}
}, [resultats, tour])
const [voixParBloc, voixParNuance] = regrouperVoix(donnees.voix, listes, blocs, nuances)
const siegesParListe = calculerSieges(listes, resultats, retirerSeuil ? 0 : 0.05) const siegesParListe = calculerSieges(listes, donnees, retirerSeuil ? 0 : 0.05)
const [siegesParBloc, siegesParNuance] = regrouperVoix(siegesParListe, listes, blocs, nuances) const [siegesParBloc, siegesParNuance] = regrouperVoix(siegesParListe, listes, blocs, nuances)
const [categoriesHistogramme, valeursHistogramme, couleursHistogramme] = useMemo(() => {
if (grouperParBloc) {
const categories = {}
const couleurs = {}
for (let bloc of blocs) {
categories[bloc.nom] = bloc.nom
couleurs[bloc.nom] = bloc.couleur
}
return [categories, voixParBloc, couleurs]
}
else {
const categories = {}
const couleurs = {}
for (let nuance of nuances) {
categories[nuance.code] = nuance.nom
couleurs[nuance.code] = nuance.couleur
}
return [categories, voixParNuance, couleurs]
}
}, [nuances, blocs, voixParNuance, voixParBloc, grouperParBloc])
return <> return <>
<AppBar position="sticky"> <AppBar position="sticky">
<Toolbar> <Toolbar>
<GroupementParBloc grouperParBloc={grouperParBloc} setGrouperParBloc={setGrouperParBloc} /> <GroupementParBloc grouperParBloc={grouperParBloc} setGrouperParBloc={setGrouperParBloc} />
<RetirerSeuil retirerSeuil={retirerSeuil} setRetirerSeuil={setRetirerSeuil} /> <RetirerSeuil retirerSeuil={retirerSeuil} setRetirerSeuil={setRetirerSeuil} />
<SelectionAffichage typeResultats={typeResultats} typeZone={typeZone} setTypeZone={setTypeZone} /> <SelectionAffichage typeResultats={typeResultats} typeSousZone={typeSousZone} setTypeSousZone={setTypeSousZone} />
</Toolbar> </Toolbar>
</AppBar> </AppBar>
<Container> <Container>
<HistogrammeVoix titre={`Résultats des élections européennes 2024 : ${nomZone}`} <HistogrammeVoix titre={`Résultats des élections européennes 2024 : ${nomZone}`}
resultats={resultats} voixParNuance={voixParNuance} voixParBloc={voixParBloc} nomCategories={categoriesHistogramme} valeurParCategorie={valeursHistogramme}
blocs={blocs} nuances={nuances} grouperParBloc={grouperParBloc} /> totalExprimes={donnees.exprimes} couleurParCategorie={couleursHistogramme} />
<CompositionHemicycle titre={`Eurodéputé⋅es français⋅es dans l'hémicycle européen 2024 : ${nomZone}`} <CompositionHemicycle titre={`Eurodéputé⋅es français⋅es dans l'hémicycle européen 2024 : ${nomZone}`}
blocs={blocs} nuances={nuances} siegesParBloc={siegesParBloc} siegesParNuance={siegesParNuance} blocs={blocs} nuances={nuances} siegesParBloc={siegesParBloc} siegesParNuance={siegesParNuance}
grouperParBloc={grouperParBloc} /> grouperParBloc={grouperParBloc} />
<TableauResultatsEuropeennes blocs={blocs} nuances={nuances} listes={listes} resultats={resultats} siegesParListe={siegesParListe} /> <TableauResultatsEuropeennes blocs={blocs} nuances={nuances} listes={listes} resultats={donnees} siegesParListe={siegesParListe} />
<TableauParticipation resultats={resultats} /> <TableauParticipation donnees_t1={donnees} />
<CarteResultats typeElection={"europeennes"} anneeElection={"2024"} <CarteResultats typeElection={"europeennes"} anneeElection={"2024"} typeResultats={typeResultats} zoneInfo={zoneInfo}
typeResultats={typeResultats} resultats={resultats} typeZone={typeZone} typeSousZone={typeSousZone} candidats={listes} blocs={blocs} nuances={nuances} tour={tour}
candidats={listes} blocs={blocs} nuances={nuances} grouperParBloc={grouperParBloc} />
voixParBloc={voixParBloc} voixParNuance={voixParNuance} grouperParBloc={grouperParBloc} />
</Container> </Container>
</> </>
} }

View File

@ -0,0 +1,148 @@
import {useParams} from "react-router-dom"
import {AppBar, Container, Toolbar} from "@mui/material"
import * as Highcharts from 'highcharts'
import highchartsItem from 'highcharts/modules/item-series'
import {useEffect, useMemo, useState} from "react"
import {
SelectionAffichage,
TableauParticipation,
CarteResultats,
HistogrammeVoix, GroupementParBloc, SelectionTour
} from "./includes/composants_elections"
import {getNomZone, regrouperVoix} from "./utils"
import 'leaflet/dist/leaflet.css'
import {
TableauResultatsCandidatsLegislatives,
TableauResultatsNuancesLegislatives
} from "./includes/composants_elections_legislatives"
highchartsItem(Highcharts)
export default function ElectionsLegislatives2022() {
const {typeResultats, zoneId} = useParams()
const [grouperParBloc, setGrouperParBloc] = useState(false)
const [tour, setTour] = useState(1)
const [blocs, setBlocs] = useState([])
const [candidats, setCandidats] = useState([])
const [nuances, setNuances] = useState([])
const [resultats, setResultats] = useState([])
const [typeSousZone, setTypeSousZone] = useState("region")
useEffect(() => {
fetch("/data/resultats/legislatives/2022/blocs.json").then(response => response.json())
.then(data => setBlocs(data))
fetch("/data/resultats/legislatives/2022/nuances.json").then(response => response.json())
.then(data => setNuances(data))
if (typeResultats === "france") {
fetch("/data/resultats/legislatives/2022/france.json").then(response => response.json())
.then(data => setResultats(data))
}
else {
fetch(`/data/resultats/legislatives/2022/${typeResultats}/${zoneId}.json`)
.then(response => response.json())
.then(data => setResultats(data))
}
}, [typeResultats, zoneId])
const zoneInfo = useMemo(() => resultats?.zone ?? {}, [resultats])
const nomZone = useMemo(() => getNomZone(typeResultats, zoneInfo), [typeResultats, zoneInfo])
useEffect(() => {
let circonscription = ""
if (typeResultats === "circonscription")
circonscription = zoneId
else if (typeResultats === "bureau_vote")
circonscription = zoneInfo?.circonscription ?? ""
else {
setCandidats(nuances)
}
if (!circonscription)
return
fetch(`/data/resultats/legislatives/2022/candidats/${circonscription}.json`)
.then(response => response.json())
.then(data => setCandidats(data))
}, [typeResultats, zoneId, zoneInfo, nuances])
const donnees = useMemo(() => {
if (tour === 1)
return resultats?.tour1 ?? {}
else if (tour === 2)
return resultats?.tour2 ?? {}
else
return {}
}, [resultats, tour])
const dejaGroupeParNuance = typeResultats !== "circonscription" && typeResultats !== "bureau_vote"
const [voixParBloc, voixParNuance] = regrouperVoix(donnees.voix, candidats, blocs, nuances,
dejaGroupeParNuance)
const candidatKey = typeSousZone === "circonscription" || typeSousZone === "bureau_vote" ? "numero" : "code"
const [categoriesHistogramme, valeursHistogramme, couleursHistogramme] = useMemo(() => {
if (grouperParBloc) {
const categories = {}
const couleurs = {}
for (let bloc of blocs) {
categories[bloc.nom] = bloc.nom
couleurs[bloc.nom] = bloc.couleur
}
return [categories, voixParBloc, couleurs]
}
else {
if (typeResultats === "circonscription" || typeResultats === "bureau_vote") {
// On affiche les noms des candidat⋅es
const categories = {}
const couleurs = {}
for (let candidat of candidats) {
categories[candidat.numero] = `${candidat.prenom} ${candidat.nom} (${candidat.nuance})`
couleurs[candidat.numero] = nuances.filter(nuance => nuance.code === candidat.nuance)[0]?.couleur
}
return [categories, donnees.voix, couleurs]
}
else {
// On affiche les nuances
const categories = {}
const couleurs = {}
for (let nuance of nuances) {
categories[nuance.code] = nuance.nom
couleurs[nuance.code] = nuance.couleur
}
return [categories, voixParNuance, couleurs]
}
}
}, [typeResultats, candidats, nuances, blocs, donnees, voixParNuance, voixParBloc, grouperParBloc])
const tableauResultats = useMemo(() => {
if (typeResultats === "circonscription" || typeResultats === "bureau_vote")
return <TableauResultatsCandidatsLegislatives candidats={candidats} blocs={blocs} nuances={nuances} donnees_t1={resultats.tour1} donnees_t2={resultats.tour2} />
else
return <TableauResultatsNuancesLegislatives blocs={blocs} nuances={nuances} donnees={donnees} />
}, [typeResultats, candidats, blocs, nuances, donnees])
return <>
<AppBar position="sticky">
<Toolbar>
<GroupementParBloc grouperParBloc={grouperParBloc} setGrouperParBloc={setGrouperParBloc} />
<SelectionAffichage typeResultats={typeResultats} typeSousZone={typeSousZone} setTypeSousZone={setTypeSousZone} />
<SelectionTour tour={tour} setTour={setTour} />
</Toolbar>
</AppBar>
<Container>
<HistogrammeVoix titre={`Résultats des élections législatives 2022 : ${nomZone}`}
nomCategories={categoriesHistogramme} valeurParCategorie={valeursHistogramme}
totalExprimes={donnees.exprimes} couleurParCategorie={couleursHistogramme} />
{tableauResultats}
<TableauParticipation donnees_t1={resultats.tour1 ?? {}} donnees_t2={resultats.tour2 ?? {}} />
<CarteResultats typeElection={"legislatives"} anneeElection={"2022"} typeResultats={typeResultats} zoneInfo={zoneInfo}
typeSousZone={typeSousZone} candidats={candidats} blocs={blocs} nuances={nuances} tour={tour}
grouperParBloc={grouperParBloc} candidatKey={candidatKey} />
</Container>
</>
}

View File

@ -0,0 +1,148 @@
import {useParams} from "react-router-dom"
import {AppBar, Container, Toolbar} from "@mui/material"
import * as Highcharts from 'highcharts'
import highchartsItem from 'highcharts/modules/item-series'
import {useEffect, useMemo, useState} from "react"
import {
SelectionAffichage,
TableauParticipation,
CarteResultats,
HistogrammeVoix, GroupementParBloc, SelectionTour
} from "./includes/composants_elections"
import {getNomZone, regrouperVoix} from "./utils"
import 'leaflet/dist/leaflet.css'
import {
TableauResultatsCandidatsLegislatives,
TableauResultatsNuancesLegislatives
} from "./includes/composants_elections_legislatives"
highchartsItem(Highcharts)
export default function ElectionsLegislatives2024() {
const {typeResultats, zoneId} = useParams()
const [grouperParBloc, setGrouperParBloc] = useState(false)
const [tour, setTour] = useState(1)
const [blocs, setBlocs] = useState([])
const [candidats, setCandidats] = useState([])
const [nuances, setNuances] = useState([])
const [resultats, setResultats] = useState([])
const [typeSousZone, setTypeSousZone] = useState("region")
useEffect(() => {
fetch("/data/resultats/legislatives/2024/blocs.json").then(response => response.json())
.then(data => setBlocs(data))
fetch("/data/resultats/legislatives/2024/nuances.json").then(response => response.json())
.then(data => setNuances(data))
if (typeResultats === "france") {
fetch("/data/resultats/legislatives/2024/france.json").then(response => response.json())
.then(data => setResultats(data))
}
else {
fetch(`/data/resultats/legislatives/2024/${typeResultats}/${zoneId}.json`)
.then(response => response.json())
.then(data => setResultats(data))
}
}, [typeResultats, zoneId])
const zoneInfo = useMemo(() => resultats?.zone ?? {}, [resultats])
const nomZone = useMemo(() => getNomZone(typeResultats, zoneInfo), [typeResultats, zoneInfo])
useEffect(() => {
let circonscription = ""
if (typeResultats === "circonscription")
circonscription = zoneId
else if (typeResultats === "bureau_vote")
circonscription = zoneInfo?.circonscription ?? ""
else {
setCandidats(nuances)
}
if (!circonscription)
return
fetch(`/data/resultats/legislatives/2024/candidats/${circonscription}.json`)
.then(response => response.json())
.then(data => setCandidats(data))
}, [typeResultats, zoneId, zoneInfo, nuances])
const donnees = useMemo(() => {
if (tour === 1)
return resultats?.tour1 ?? {}
else if (tour === 2)
return resultats?.tour2 ?? {}
else
return {}
}, [resultats, tour])
const dejaGroupeParNuance = typeResultats !== "circonscription" && typeResultats !== "bureau_vote"
const [voixParBloc, voixParNuance] = regrouperVoix(donnees.voix, candidats, blocs, nuances,
dejaGroupeParNuance)
const candidatKey = typeSousZone === "circonscription" || typeSousZone === "bureau_vote" ? "numero" : "code"
const [categoriesHistogramme, valeursHistogramme, couleursHistogramme] = useMemo(() => {
if (grouperParBloc) {
const categories = {}
const couleurs = {}
for (let bloc of blocs) {
categories[bloc.nom] = bloc.nom
couleurs[bloc.nom] = bloc.couleur
}
return [categories, voixParBloc, couleurs]
}
else {
if (typeResultats === "circonscription" || typeResultats === "bureau_vote") {
// On affiche les noms des candidat⋅es
const categories = {}
const couleurs = {}
for (let candidat of candidats) {
categories[candidat.numero] = `${candidat.prenom} ${candidat.nom} (${candidat.nuance})`
couleurs[candidat.numero] = nuances.filter(nuance => nuance.code === candidat.nuance)[0]?.couleur
}
return [categories, donnees.voix, couleurs]
}
else {
// On affiche les nuances
const categories = {}
const couleurs = {}
for (let nuance of nuances) {
categories[nuance.code] = nuance.nom
couleurs[nuance.code] = nuance.couleur
}
return [categories, voixParNuance, couleurs]
}
}
}, [typeResultats, candidats, nuances, blocs, donnees, voixParNuance, voixParBloc, grouperParBloc])
const tableauResultats = useMemo(() => {
if (typeResultats === "circonscription" || typeResultats === "bureau_vote")
return <TableauResultatsCandidatsLegislatives candidats={candidats} blocs={blocs} nuances={nuances} donnees_t1={resultats.tour1} donnees_t2={resultats.tour2} />
else
return <TableauResultatsNuancesLegislatives blocs={blocs} nuances={nuances} donnees={donnees} />
}, [typeResultats, candidats, blocs, nuances, donnees])
return <>
<AppBar position="sticky">
<Toolbar>
<GroupementParBloc grouperParBloc={grouperParBloc} setGrouperParBloc={setGrouperParBloc} />
<SelectionAffichage typeResultats={typeResultats} typeSousZone={typeSousZone} setTypeSousZone={setTypeSousZone} />
<SelectionTour tour={tour} setTour={setTour} />
</Toolbar>
</AppBar>
<Container>
<HistogrammeVoix titre={`Résultats des élections législatives 2024 : ${nomZone}`}
nomCategories={categoriesHistogramme} valeurParCategorie={valeursHistogramme}
totalExprimes={donnees.exprimes} couleurParCategorie={couleursHistogramme} />
{tableauResultats}
<TableauParticipation donnees_t1={resultats.tour1 ?? {}} donnees_t2={resultats.tour2 ?? {}} />
<CarteResultats typeElection={"legislatives"} anneeElection={"2024"} typeResultats={typeResultats} zoneInfo={zoneInfo}
typeSousZone={typeSousZone} candidats={candidats} blocs={blocs} nuances={nuances} tour={tour}
grouperParBloc={grouperParBloc} candidatKey={candidatKey} />
</Container>
</>
}

View File

@ -16,25 +16,21 @@ import Switch from "@mui/material/Switch";
import FormControlLabel from "@mui/material/FormControlLabel"; import FormControlLabel from "@mui/material/FormControlLabel";
export function HistogrammeVoix({titre, resultats, voixParNuance, voixParBloc, blocs, nuances, grouperParBloc}) { export function HistogrammeVoix({titre, nomCategories, valeurParCategorie, totalExprimes, couleurParCategorie}) {
const [categoriesVoix, dataVoix] = useMemo(() => { const [categoriesVoix, dataVoix] = useMemo(() => {
const categories = [] const categories = []
const data = [] const data = []
if (grouperParBloc) {
for (let bloc of blocs) { for (let categorie of Object.keys(nomCategories)) {
categories.push(bloc.nom) if (valeurParCategorie[categorie] !== 0) {
data.push([bloc.nom, voixParBloc[bloc.nom], bloc.couleur, bloc.nom]) categories.push(nomCategories[categorie])
} data.push([nomCategories[categorie], valeurParCategorie[categorie], couleurParCategorie[categorie],
} nomCategories[categorie]])
else {
for (let nuance of nuances) {
categories.push(nuance.nom)
data.push([nuance.nom, voixParNuance[nuance.code], nuance.couleur, nuance.nom])
} }
} }
return [categories, data] return [categories, data]
}, [voixParBloc, voixParNuance, blocs, nuances, grouperParBloc]) }, [nomCategories, valeurParCategorie, couleurParCategorie])
const scoreOptions = { const scoreOptions = {
chart: { chart: {
@ -45,7 +41,7 @@ export function HistogrammeVoix({titre, resultats, voixParNuance, voixParBloc, b
}, },
tooltip: { tooltip: {
formatter: function () { formatter: function () {
return `<span>${this.x}</span> : <strong>${this.y}</strong> voix (${(100 * this.y / resultats.exprimes).toFixed(2)} %)<br>` return `<span>${this.x}</span> : <strong>${this.y}</strong> voix (${(100 * this.y / totalExprimes).toFixed(2)} %)<br>`
} }
}, },
xAxis: { xAxis: {
@ -115,59 +111,142 @@ export function CompositionHemicycle({titre, blocs, nuances, siegesParBloc, sieg
/** /**
* Tableau de participation de l'élection dans la zone concernée * Tableau de participation de l'élection dans la zone concernée
* @param resultats * @param donnees_t1
* @param donnees_t2
* @return {JSX.Element} * @return {JSX.Element}
* @constructor * @constructor
*/ */
export function TableauParticipation({resultats}) { export function TableauParticipation({donnees_t1, donnees_t2 = null}) {
return <> const headerRow = useMemo(() => {
<TableContainer component={Paper}> if (donnees_t2 && donnees_t2.inscrits) {
<Table sx={{ minWidth: 650 }} aria-label="simple table"> return <TableRow>
<TableHead> <TableCell></TableCell>
<TableRow> <TableCell>Nombre tour 1</TableCell>
<TableCell>% Inscrites tour 1</TableCell>
<TableCell>% Votantes tour 1</TableCell>
<TableCell>Nombre tour 2</TableCell>
<TableCell>% Inscrites tour 2</TableCell>
<TableCell>% Votantes tour 2</TableCell>
</TableRow>
}
else {
return <TableRow>
<TableCell></TableCell> <TableCell></TableCell>
<TableCell>Nombre</TableCell> <TableCell>Nombre</TableCell>
<TableCell>% Inscrites</TableCell> <TableCell>% Inscrites</TableCell>
<TableCell>% Votantes</TableCell> <TableCell>% Votantes</TableCell>
</TableRow> </TableRow>
</TableHead> }
<TableBody> }, [donnees_t2])
const bodyRows = useMemo(() => {
if (donnees_t2 && donnees_t2.inscrits) {
return <>
<TableRow key={"Inscrit⋅es"}> <TableRow key={"Inscrit⋅es"}>
<TableCell>Inscrites</TableCell> <TableCell>Inscrites</TableCell>
<TableCell>{resultats.inscrits}</TableCell> <TableCell>{donnees_t1.inscrits}</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell>{donnees_t2.inscrits}</TableCell>
<TableCell></TableCell> <TableCell></TableCell>
<TableCell></TableCell> <TableCell></TableCell>
</TableRow> </TableRow>
<TableRow key={"Abstentions"}> <TableRow key={"Abstentions"}>
<TableCell>Abstention</TableCell> <TableCell>Abstention</TableCell>
<TableCell>{resultats.abstentions}</TableCell> <TableCell>{donnees_t1.abstentions}</TableCell>
<TableCell>{(100 * resultats.abstentions / resultats.inscrits).toFixed(2)} %</TableCell> <TableCell>{(100 * donnees_t1.abstentions / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell></TableCell>
<TableCell>{donnees_t2.abstentions}</TableCell>
<TableCell>{(100 * donnees_t2.abstentions / donnees_t2.inscrits).toFixed(2)} %</TableCell>
<TableCell></TableCell> <TableCell></TableCell>
</TableRow> </TableRow>
<TableRow key={"Votant⋅es"}> <TableRow key={"Votant⋅es"}>
<TableCell>Votantes</TableCell> <TableCell>Votantes</TableCell>
<TableCell>{resultats.votants}</TableCell> <TableCell>{donnees_t1.votants}</TableCell>
<TableCell>{(100 * resultats.votants / resultats.inscrits).toFixed(2)} %</TableCell> <TableCell>{(100 * donnees_t1.votants / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell></TableCell>
<TableCell>{donnees_t2.votants}</TableCell>
<TableCell>{(100 * donnees_t2.votants / donnees_t2.inscrits).toFixed(2)} %</TableCell>
<TableCell></TableCell> <TableCell></TableCell>
</TableRow> </TableRow>
<TableRow key={"Blancs"}> <TableRow key={"Blancs"}>
<TableCell>Blancs</TableCell> <TableCell>Blancs</TableCell>
<TableCell>{resultats.blancs}</TableCell> <TableCell>{donnees_t1.blancs}</TableCell>
<TableCell>{(100 * resultats.blancs / resultats.inscrits).toFixed(2)} %</TableCell> <TableCell>{(100 * donnees_t1.blancs / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * resultats.blancs / resultats.votants).toFixed(2)} %</TableCell> <TableCell>{(100 * donnees_t1.blancs / donnees_t1.votants).toFixed(2)} %</TableCell>
<TableCell>{donnees_t2.blancs}</TableCell>
<TableCell>{(100 * donnees_t2.blancs / donnees_t2.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * donnees_t2.blancs / donnees_t2.votants).toFixed(2)} %</TableCell>
</TableRow> </TableRow>
<TableRow key={"Nuls"}> <TableRow key={"Nuls"}>
<TableCell>Nuls</TableCell> <TableCell>Nuls</TableCell>
<TableCell>{resultats.nuls}</TableCell> <TableCell>{donnees_t1.nuls}</TableCell>
<TableCell>{(100 * resultats.nuls / resultats.inscrits).toFixed(2)} %</TableCell> <TableCell>{(100 * donnees_t1.nuls / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * resultats.nuls / resultats.votants).toFixed(2)} %</TableCell> <TableCell>{(100 * donnees_t1.nuls / donnees_t1.votants).toFixed(2)} %</TableCell>
<TableCell>{donnees_t2.nuls}</TableCell>
<TableCell>{(100 * donnees_t2.nuls / donnees_t2.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * donnees_t2.nuls / donnees_t2.votants).toFixed(2)} %</TableCell>
</TableRow> </TableRow>
<TableRow key={"Exprimés"}> <TableRow key={"Exprimés"}>
<TableCell>Exprimés</TableCell> <TableCell>Exprimés</TableCell>
<TableCell>{resultats.exprimes}</TableCell> <TableCell>{donnees_t1.exprimes}</TableCell>
<TableCell>{(100 * resultats.exprimes / resultats.inscrits).toFixed(2)} %</TableCell> <TableCell>{(100 * donnees_t1.exprimes / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * resultats.exprimes / resultats.votants).toFixed(2)} %</TableCell> <TableCell>{(100 * donnees_t1.exprimes / donnees_t1.votants).toFixed(2)} %</TableCell>
<TableCell>{donnees_t2.exprimes}</TableCell>
<TableCell>{(100 * donnees_t2.exprimes / donnees_t2.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * donnees_t2.exprimes / donnees_t2.votants).toFixed(2)} %</TableCell>
</TableRow> </TableRow>
</>
} else {
return <>
<TableRow key={"Inscrit⋅es"}>
<TableCell>Inscrites</TableCell>
<TableCell>{donnees_t1.inscrits}</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow key={"Abstentions"}>
<TableCell>Abstention</TableCell>
<TableCell>{donnees_t1.abstentions}</TableCell>
<TableCell>{(100 * donnees_t1.abstentions / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow key={"Votant⋅es"}>
<TableCell>Votantes</TableCell>
<TableCell>{donnees_t1.votants}</TableCell>
<TableCell>{(100 * donnees_t1.votants / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow key={"Blancs"}>
<TableCell>Blancs</TableCell>
<TableCell>{donnees_t1.blancs}</TableCell>
<TableCell>{(100 * donnees_t1.blancs / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * donnees_t1.blancs / donnees_t1.votants).toFixed(2)} %</TableCell>
</TableRow>
<TableRow key={"Nuls"}>
<TableCell>Nuls</TableCell>
<TableCell>{donnees_t1.nuls}</TableCell>
<TableCell>{(100 * donnees_t1.nuls / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * donnees_t1.nuls / donnees_t1.votants).toFixed(2)} %</TableCell>
</TableRow>
<TableRow key={"Exprimés"}>
<TableCell>Exprimés</TableCell>
<TableCell>{donnees_t1.exprimes}</TableCell>
<TableCell>{(100 * donnees_t1.exprimes / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * donnees_t1.exprimes / donnees_t1.votants).toFixed(2)} %</TableCell>
</TableRow>
</>
}
}, [donnees_t1, donnees_t2])
return <>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
{headerRow}
</TableHead>
<TableBody>
{bodyRows}
</TableBody> </TableBody>
</Table> </Table>
</TableContainer> </TableContainer>
@ -184,23 +263,37 @@ export function RetirerSeuil({retirerSeuil, setRetirerSeuil}) {
label="Retirer le seuil des 5 %" /> label="Retirer le seuil des 5 %" />
} }
export function SelectionAffichage({typeResultats, typeZone, setTypeZone}) { export function SelectionTour({tour, setTour}) {
return <FormControl>
<InputLabel>
Zone à afficher
</InputLabel>
<Select value={tour}
onChange={event => setTour(parseInt(event.target.value.toString()))}
label="Tour">
<MenuItem value="1">Tour 1</MenuItem>
<MenuItem value="2">Tour 2</MenuItem>
</Select>
</FormControl>
}
export function SelectionAffichage({typeResultats, typeSousZone, setTypeSousZone}) {
const items = useMemo(() => { const items = useMemo(() => {
const items = [] const items = []
if (typeResultats === "france") { if (typeResultats === "france") {
setTypeZone("region") setTypeSousZone("region")
items.push(<MenuItem value="region">Région</MenuItem>) items.push(<MenuItem value="region">Région</MenuItem>)
} }
if (typeResultats === "france" || typeResultats === "region") { if (typeResultats === "france" || typeResultats === "region") {
if (typeResultats !== "france") if (typeResultats !== "france")
setTypeZone("departement") setTypeSousZone("departement")
items.push(<MenuItem value="departement">Département</MenuItem>) items.push(<MenuItem value="departement">Département</MenuItem>)
} }
if (typeResultats === "france" || typeResultats === "region" || typeResultats === "departement") { if (typeResultats === "france" || typeResultats === "region" || typeResultats === "departement") {
if (typeResultats !== "france" && typeResultats !== "region") if (typeResultats !== "france" && typeResultats !== "region")
setTypeZone("circonscription") setTypeSousZone("circonscription")
items.push(<MenuItem value="circonscription">Circonscription</MenuItem>) items.push(<MenuItem value="circonscription">Circonscription</MenuItem>)
} }
@ -209,19 +302,19 @@ export function SelectionAffichage({typeResultats, typeZone, setTypeZone}) {
} }
if (typeResultats === "circonscription" || typeResultats === "commune" || typeResultats === "bureau_vote") { if (typeResultats === "circonscription" || typeResultats === "commune" || typeResultats === "bureau_vote") {
setTypeZone("bureau_vote") setTypeSousZone("bureau_vote")
items.push(<MenuItem value="bureau_vote">Bureau de vote</MenuItem>) items.push(<MenuItem value="bureau_vote">Bureau de vote</MenuItem>)
} }
return items return items
}, [typeResultats, setTypeZone]) }, [typeResultats, setTypeSousZone])
return <FormControl> return <FormControl>
<InputLabel> <InputLabel>
Zone à afficher Zone à afficher
</InputLabel> </InputLabel>
<Select value={typeZone} <Select value={typeSousZone}
onChange={event => setTypeZone(event.target.value)} onChange={event => setTypeSousZone(event.target.value)}
label="Zone à afficher"> label="Zone à afficher">
{items} {items}
</Select> </Select>
@ -229,26 +322,44 @@ export function SelectionAffichage({typeResultats, typeZone, setTypeZone}) {
} }
function ZoneGeoJSON({typeElection, anneeElection, resultatsZone, typeZone, function ZoneGeoJSON({typeElection, anneeElection, resultatsZone, typeSousZone,
candidats, blocs, nuances, grouperParBloc = false}) { candidats, blocs, nuances, tour, grouperParBloc = false, candidatKey = "numero"}) {
const sousZoneInfo = resultatsZone.zone
const donnees = useMemo(() => {
return resultatsZone ? (tour === 1 ? resultatsZone.tour1 : resultatsZone.tour2) : {}
}, [resultatsZone, tour])
const [idZone, nomZone] = useMemo(() => { const [idZone, nomZone] = useMemo(() => {
if (!resultatsZone[typeZone]) if (!sousZoneInfo)
return ["", ""] return ["", ""]
if (typeZone === "region" || typeZone === "departement" || typeZone === "commune") if (typeSousZone === "region" || typeSousZone === "departement" || typeSousZone === "commune")
return [resultatsZone[typeZone].code_insee, resultatsZone[typeZone].nom] return [sousZoneInfo.code_insee, sousZoneInfo.nom]
else if (typeZone === "circonscription") else if (typeSousZone === "circonscription")
return [resultatsZone.circonscription.id, `Circonscription ${resultatsZone.circonscription.id}`] return [sousZoneInfo.id, `Circonscription ${sousZoneInfo.id}`]
else if (typeZone === "bureau_vote") else if (typeSousZone === "bureau_vote")
return [resultatsZone.bureau_vote.id, resultatsZone.bureau_vote.libelle] return [sousZoneInfo.id, sousZoneInfo.libelle]
else else
return ["", ""] return ["", ""]
}, [typeZone, resultatsZone]) }, [typeSousZone, sousZoneInfo])
const voixCandidats = useMemo(() => resultatsZone?.voix ?? {}, [resultatsZone]) const [candidatsZone, setCandidatsZone] = useState(candidats)
const candidatsTries = trierCandidats(candidats, voixCandidats) useEffect(() => {
if (typeElection === "legislatives" && (typeSousZone === "circonscription" || typeSousZone === "bureau_vote") && sousZoneInfo.id) {
const circo_id = typeSousZone === "circonscription" ? sousZoneInfo.id : sousZoneInfo.circonscription
fetch(`/data/resultats/${typeElection}/${anneeElection}/candidats/${circo_id}.json`)
.then(response => response.json())
.then(data => setCandidatsZone(data))
}
}, [typeElection, anneeElection, typeSousZone, sousZoneInfo])
const [voixParBloc, voixParNuance] = regrouperVoix(voixCandidats, candidats, blocs, nuances) const voixCandidats = useMemo(() => donnees?.voix ?? {}, [donnees])
const candidatsTries = trierCandidats(candidatsZone, voixCandidats, candidatKey)
const dejaGroupesParNuance = typeElection === "legislatives"
&& (typeSousZone !== "circonscription" && typeSousZone !== "bureau_vote")
const [voixParBloc, voixParNuance] = regrouperVoix(voixCandidats, candidatsZone, blocs, nuances,
dejaGroupesParNuance)
let couleur = 'grey' let couleur = 'grey'
if (grouperParBloc) { if (grouperParBloc) {
@ -271,59 +382,58 @@ function ZoneGeoJSON({typeElection, anneeElection, resultatsZone, typeZone,
} }
return <GeoJSON return <GeoJSON
data={{'type': "Feature", 'geometry': resultatsZone.geometry}} data={{'type': "Feature", 'geometry': resultatsZone.zone.geometry}}
style={{fillColor: couleur, fillOpacity: 0.5, color: 'white', weight: 1}}> style={{fillColor: couleur, fillOpacity: 0.5, color: 'white', weight: 1}}>
<Popup> <Popup>
<strong><a href={`/elections/${typeElection}/${anneeElection}/${typeZone}/${idZone}/`}>{nomZone}</a></strong> <strong><a href={`/elections/${typeElection}/${anneeElection}/${typeSousZone}/${idZone}/`}>{nomZone}</a></strong>
<ul> <ul>
{candidatsTries.slice(0, 5).map(candidat => {candidatsTries.slice(0, 5).map(candidat =>
<li key={candidat.numero}> <li key={candidat[candidatKey]}>
{candidat.nom} : {voixCandidats[candidat.numero]} ({(100 * voixCandidats[candidat.numero] / resultatsZone.exprimes).toFixed(2)} %) {candidat.nom} : {voixCandidats[candidat[candidatKey]]} ({(100 * voixCandidats[candidat[candidatKey]] / donnees.exprimes).toFixed(2)} %)
</li>)} </li>)}
</ul> </ul>
</Popup> </Popup>
</GeoJSON> </GeoJSON>
} }
function ContenuCarte({typeElection, anneeElection, typeResultats, resultats, function ContenuCarte({typeElection, anneeElection, zoneInfo, typeSousZone, candidats, blocs, nuances, tour,
typeZone, candidats, blocs, nuances, grouperParBloc = false}) { grouperParBloc = false, candidatKey = "numero"}) {
const map = useMap() const map = useMap()
const [resultatsZones, setResultatsZones] = useState([]) const [resultatsZones, setResultatsZones] = useState([])
const zones = useMemo(() => { const zones = useMemo(() => {
const data = resultats[typeResultats] if (!zoneInfo)
if (!data)
return [] return []
if (typeZone === "region") if (typeSousZone === "region")
return data?.regions ?? [] return zoneInfo?.regions ?? []
else if (typeZone === "departement") else if (typeSousZone === "departement")
return data?.departements ?? [] return zoneInfo?.departements ?? []
else if (typeZone === "circonscription") else if (typeSousZone === "circonscription")
return data?.circonscriptions ?? [] return zoneInfo?.circonscriptions ?? []
else if (typeZone === "commune") else if (typeSousZone === "commune")
return data?.communes ?? [] return zoneInfo?.communes ?? []
else if (typeZone === "bureau_vote") { else if (typeSousZone === "bureau_vote") {
if (typeResultats === "bureau_vote") if (zoneInfo.type === "bureau_vote")
return data ? [data.id] : [] return zoneInfo ? [zoneInfo.id] : []
else else
return data?.bureaux_vote ?? [] return zoneInfo?.bureaux_vote ?? []
} }
else else
return [] return []
}, [typeResultats, resultats, typeZone]) }, [zoneInfo, typeSousZone])
useEffect(() => { useEffect(() => {
if (typeResultats === "france") if (zoneInfo.type === "france")
return return
const geometry = resultats.geometry const geometry = zoneInfo.geometry
if (geometry) { if (geometry) {
// On centre la carte sur la zone // On centre la carte sur la zone
const geometry_bbox = bbox(geometry) const geometry_bbox = bbox(geometry)
map.fitBounds([[geometry_bbox[1], geometry_bbox[0]], [geometry_bbox[3], geometry_bbox[2]]]) map.fitBounds([[geometry_bbox[1], geometry_bbox[0]], [geometry_bbox[3], geometry_bbox[2]]])
} }
}, [typeResultats, resultats, map]) }, [zoneInfo, map])
useEffect(() => { useEffect(() => {
if (!zones) if (!zones)
@ -332,32 +442,33 @@ function ContenuCarte({typeElection, anneeElection, typeResultats, resultats,
setResultatsZones(resultatsZones => []) setResultatsZones(resultatsZones => [])
zones.forEach(zoneId => { zones.forEach(zoneId => {
fetch(`/data/resultats/${typeElection}/${anneeElection}/${typeZone}/${zoneId}.json`) fetch(`/data/resultats/${typeElection}/${anneeElection}/${typeSousZone}/${zoneId}.json`)
.then(response => response.json()) .then(response => response.json())
.then(resultatsZone => setResultatsZones(resultatsZones => [...resultatsZones, resultatsZone])) .then(resultatsZone => setResultatsZones(resultatsZones => [...resultatsZones, resultatsZone]))
}) })
}, [typeElection, anneeElection, typeZone, zones, resultats]) }, [typeElection, anneeElection, typeSousZone, zones])
function getZoneIdentifier(typeZone, zone) { function getZoneIdentifier(typeSousZone, zone) {
if (typeZone === "region" || typeZone === "departement" || typeZone === "commune") if (typeSousZone === "region" || typeSousZone === "departement" || typeSousZone === "commune")
return zone.code_insee return zone.code_insee
else if (typeZone === "circonscription" || typeZone === "bureau_vote") else if (typeSousZone === "circonscription" || typeSousZone === "bureau_vote")
return zone.id return zone.id
else else
return "" return ""
} }
return <> return <>
{resultatsZones.filter(resultatsZone => resultatsZone.geometry['type']).map(resultatsZone => {resultatsZones.filter(resultatsZone => resultatsZone.zone.geometry['type'])
<ZoneGeoJSON key={getZoneIdentifier(resultatsZone[typeZone])} .map(resultatsZone =>
<ZoneGeoJSON key={getZoneIdentifier(typeSousZone, resultatsZone.zone)}
typeElection={typeElection} anneeElection={anneeElection} typeElection={typeElection} anneeElection={anneeElection}
resultatsZone={resultatsZone} typeZone={typeZone} candidats={candidats} resultatsZone={resultatsZone} typeSousZone={typeSousZone} candidats={candidats}
blocs={blocs} nuances={nuances} grouperParBloc={grouperParBloc}/>)} blocs={blocs} nuances={nuances} tour={tour} grouperParBloc={grouperParBloc} candidatKey={candidatKey} />)}
</> </>
} }
export function CarteResultats({typeElection, anneeElection, typeResultats, resultats, export function CarteResultats({typeElection, anneeElection, typeResultats, zoneInfo, typeSousZone, candidats,
typeZone, candidats, blocs, nuances, grouperParBloc = false}) { blocs, nuances, tour, grouperParBloc = false, candidatKey = "numero"}) {
const center = typeResultats === "france" ? [46.603354, 1.888334] : [0, 0] const center = typeResultats === "france" ? [46.603354, 1.888334] : [0, 0]
return <> return <>
@ -366,9 +477,9 @@ export function CarteResultats({typeElection, anneeElection, typeResultats, resu
attribution='&copy; Les contributeur⋅rices <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>' attribution='&copy; Les contributeur⋅rices <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/> />
<ContenuCarte typeElection={typeElection} anneeElection={anneeElection} typeResultats={typeResultats} <ContenuCarte typeElection={typeElection} anneeElection={anneeElection}
resultats={resultats} typeZone={typeZone} candidats={candidats} zoneInfo={zoneInfo} typeSousZone={typeSousZone} candidats={candidats}
blocs={blocs} nuances={nuances} grouperParBloc={grouperParBloc} /> blocs={blocs} nuances={nuances} tour={tour} grouperParBloc={grouperParBloc} candidatKey={candidatKey} />
</MapContainer> </MapContainer>
</> </>
} }

View File

@ -0,0 +1,133 @@
import {trierCandidats} from "../utils"
import TableContainer from "@mui/material/TableContainer"
import Paper from "@mui/material/Paper"
import Table from "@mui/material/Table"
import TableHead from "@mui/material/TableHead"
import TableRow from "@mui/material/TableRow"
import TableCell from "@mui/material/TableCell"
import TableBody from "@mui/material/TableBody"
export function TableauResultatsCandidatsLegislatives({blocs, candidats, nuances, donnees_t1, donnees_t2}) {
const voixCandidats_t1 = donnees_t1?.voix ?? {}
const voixCandidats_t2 = donnees_t2?.voix ?? {}
const candidatsTriees = trierCandidats(candidats, voixCandidats_t1)
const cellules_t1 = <>
<TableCell>Voix tour 1</TableCell>
<TableCell>% Inscrites tour 1</TableCell>
<TableCell>% Exprimées tour 1</TableCell>
</>
const cellules_t2 = Math.max(...Object.values(voixCandidats_t2)) === 0 ? <></> : <>
<TableCell>Voix tour 2</TableCell>
<TableCell>% Inscrites tour 2</TableCell>
<TableCell>% Exprimées tour 2</TableCell>
</>
return <>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Numéro</TableCell>
<TableCell>Candidat</TableCell>
<TableCell colSpan={2}>Nuance</TableCell>
<TableCell colSpan={2}>Bloc</TableCell>
{cellules_t1}
{cellules_t2}
</TableRow>
</TableHead>
<TableBody>
{candidatsTriees.map((candidat) => (
<LigneCandidat key={candidat.numero} candidat={candidat}
voix_t1={voixCandidats_t1[candidat.numero] || 0}
voix_t2={voixCandidats_t2[candidat.numero] || 0}
donnees_t1={donnees_t1} donnees_t2={donnees_t2}
nuances={nuances} blocs={blocs} />
))}
</TableBody>
</Table>
</TableContainer>
</>
}
function LigneCandidat({candidat, voix_t1, voix_t2, donnees_t1, donnees_t2, nuances, blocs}) {
const nuance = nuances.filter(nuance => nuance.code === candidat.nuance)[0]
const bloc = blocs.filter(bloc => bloc.nom === candidat.bloc)[0]
const gagnant = (voix_t2 > 0 && voix_t2 === Math.max(...Object.values(donnees_t2.voix)))
|| (voix_t1 === Math.max(...Object.values(donnees_t1.voix))
&& voix_t1 / donnees_t1.exprimes >= 0.5 && voix_t1 / donnees_t1.inscrits >= 0.25)
const cellules_t1 = <>
<TableCell>{voix_t1}</TableCell>
<TableCell>{(100 * voix_t1 / donnees_t1.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * voix_t1 / donnees_t1.exprimes).toFixed(2)} %</TableCell>
</>
const cellules_t2 = !voix_t2 ? <></> : <>
<TableCell>{voix_t2}</TableCell>
<TableCell>{(100 * voix_t2 / donnees_t2.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * voix_t2 / donnees_t2.exprimes).toFixed(2)} %</TableCell>
</>
return <TableRow sx={{backgroundColor: gagnant ? "#AAFFAA" : ""}} key={candidat.numero}>
<TableCell>{candidat.numero}</TableCell>
<TableCell>{candidat.prenom} {candidat.nom}</TableCell>
<TableCell sx={{backgroundColor: nuance.couleur, padding: "0.2em"}}></TableCell>
<TableCell>{nuance.nom} ({nuance.code})</TableCell>
<TableCell sx={{backgroundColor: bloc.couleur, padding: "0.2em"}}></TableCell>
<TableCell>{bloc.nom}</TableCell>
{cellules_t1}
{cellules_t2}
</TableRow>
}
/**
* Composant pour le tableau des résultats des élections législatives
* @param blocs
* @param nuances
* @param donnees
* @return {JSX.Element}
* @constructor
*/
export function TableauResultatsNuancesLegislatives({blocs, nuances, donnees}) {
const voixNuances = donnees?.voix ?? {}
const nuancesTriees = trierCandidats(nuances, voixNuances, "code")
return <>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell colSpan={2}>Nuance</TableCell>
<TableCell colSpan={2}>Bloc</TableCell>
<TableCell>Voix</TableCell>
<TableCell>% Inscrites</TableCell>
<TableCell>% Exprimées</TableCell>
</TableRow>
</TableHead>
<TableBody>
{nuancesTriees.map((nuance) => (
<LigneNuance key={nuance.code} nuance={nuance} voix={voixNuances[nuance.code] || 0}
donnees={donnees} blocs={blocs} />
))}
</TableBody>
</Table>
</TableContainer>
</>
}
function LigneNuance({nuance, voix, donnees, blocs}) {
const bloc = blocs.filter(bloc => bloc.nom === nuance.bloc)[0]
return <TableRow key={nuance.code}>
<TableCell sx={{backgroundColor: nuance.couleur, padding: "0.2em"}}></TableCell>
<TableCell>{nuance.nom} ({nuance.code})</TableCell>
<TableCell sx={{backgroundColor: bloc.couleur, padding: "0.2em"}}></TableCell>
<TableCell>{bloc.nom}</TableCell>
<TableCell>{voix}</TableCell>
<TableCell>{(100 * voix / donnees.inscrits).toFixed(2)} %</TableCell>
<TableCell>{(100 * voix / donnees.exprimes).toFixed(2)} %</TableCell>
</TableRow>
}

View File

@ -1,44 +1,50 @@
export function getNomZone(typeResultats, resultats) { export function getNomZone(typeResultats, zoneInfo) {
if (!resultats || resultats.length === 0) if (!zoneInfo.type)
return "" return ""
else if (typeResultats === "france") else if (typeResultats === "france")
return "France" return "France"
else if (typeResultats === "region") else if (typeResultats === "region")
return `Région ${resultats.region.nom}` return `Région ${zoneInfo.nom}`
else if (typeResultats === "departement") else if (typeResultats === "departement")
return `Département ${resultats.departement.nom}` return `Département ${zoneInfo.nom}`
else if (typeResultats === "circonscription") else if (typeResultats === "circonscription")
return `Circonscription ${resultats.circonscription.id}` return `Circonscription ${zoneInfo.id}`
else if (typeResultats === "commune") else if (typeResultats === "commune")
return `Commune ${resultats.commune.nom}` return `Commune ${zoneInfo.nom}`
else if (typeResultats === "bureau_vote") else if (typeResultats === "bureau_vote")
return resultats.bureau_vote.libelle return zoneInfo.libelle
} }
export function trierCandidats(candidats, voix_par_candidat) { export function trierCandidats(candidats, voix_par_candidat, key = "numero") {
return candidats.toSorted((l1, l2) => { return candidats.toSorted((l1, l2) => {
return (voix_par_candidat[l2.numero] || 0) - (voix_par_candidat[l1.numero] || 0) return (voix_par_candidat[l2[key]] || 0) - (voix_par_candidat[l1[key]] || 0)
}) })
} }
export function regrouperVoix(voixCandidats, candidats, blocs, nuances) { export function regrouperVoix(voixCandidats, candidats, blocs, nuances, dejaGroupesParNuance = false) {
if (!candidats || !voixCandidats || !blocs || !nuances if (!candidats || !voixCandidats || !blocs || !nuances
|| candidats.length === 0 || blocs.length === 0 || nuances.length === 0) || candidats.length === 0 || blocs.length === 0 || nuances.length === 0)
return [{}, {}] return [{}, {}]
const key = dejaGroupesParNuance ? "code" : "numero"
const parBloc = {} const parBloc = {}
const parNuance = {} const parNuance = dejaGroupesParNuance ? voixCandidats : {}
for (let bloc of blocs) { for (let bloc of blocs) {
parBloc[bloc.nom] = 0 parBloc[bloc.nom] = 0
} }
if (!dejaGroupesParNuance) {
for (let nuance of nuances) { for (let nuance of nuances) {
parNuance[nuance.code] = 0 parNuance[nuance.code] = 0
} }
}
for (let candidat of candidats) { for (let candidat of candidats) {
parBloc[candidat.bloc] += voixCandidats[candidat.numero] || 0 parBloc[candidat.bloc] += voixCandidats[candidat[key]] || 0
parNuance[candidat.nuance] += voixCandidats[candidat.numero] || 0 if (!dejaGroupesParNuance)
parNuance[candidat.nuance] += voixCandidats[candidat[key]] || 0
} }
return [parBloc, parNuance] return [parBloc, parNuance]

View File

@ -1,3 +1,5 @@
from .base import Base from .base import Base
from .geographie import * from .geographie import *
from .legislatives2022 import *
from .europeennes2024 import * from .europeennes2024 import *
from .legislatives2024 import *

View File

@ -1,5 +1,23 @@
import enum
from sqlalchemy.orm import DeclarativeBase from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase): class Base(DeclarativeBase):
pass pass
class Genre(enum.Enum):
MASCULIN = "M"
FEMININ = "F"
class Personnalite(enum.Enum):
DEFAUT = ""
EURODEPUTE = "RPE"
DEPUTE = "DEP"
SENATEUR = "SEN"
MINISTRE = "MIN"
PRESIDENT_CONSEIL_REGIONAL = "PCR"
PRESIDENT_CONSEIL_DEPARTEMENTAL = "PCD"
MAIRE = "MAI"

View File

@ -6,6 +6,7 @@ from sqlalchemy import Boolean, Date, Enum, ForeignKey, Integer, String
from sqlalchemy.orm import mapped_column, Mapped, relationship from sqlalchemy.orm import mapped_column, Mapped, relationship
from nupes.models import Base, Region, Departement, Commune from nupes.models import Base, Region, Departement, Commune
from nupes.models.base import Genre, Personnalite
class BlocEuropeennes2024(Base): class BlocEuropeennes2024(Base):
@ -59,20 +60,6 @@ class ListeEuropeennes2024(Base):
class CandidatEuropeennes2024(Base): class CandidatEuropeennes2024(Base):
class Genre(enum.Enum):
MASCULIN = "M"
FEMININ = "F"
class Personnalite(enum.Enum):
DEFAUT = ""
EURODEPUTE = "RPE"
DEPUTE = "DEP"
SENATEUR = "SEN"
MINISTRE = "MIN"
PRESIDENT_CONSEIL_REGIONAL = "PCR"
PRESIDENT_CONSEIL_DEPARTEMENTAL = "PCD"
MAIRE = "MAI"
__tablename__ = "europeennes_2024_candidat" __tablename__ = "europeennes_2024_candidat"
id: Mapped[int] = mapped_column(primary_key=True) id: Mapped[int] = mapped_column(primary_key=True)
@ -80,10 +67,10 @@ class CandidatEuropeennes2024(Base):
ordre: Mapped[int] = mapped_column(Integer()) ordre: Mapped[int] = mapped_column(Integer())
nom: Mapped[str] = mapped_column(String(256)) nom: Mapped[str] = mapped_column(String(256))
prenom: Mapped[str] = mapped_column(String(256)) prenom: Mapped[str] = mapped_column(String(256))
sexe: Mapped[str] = mapped_column(Enum(Genre)) sexe: Mapped[str] = mapped_column(Enum(Genre, name="europeennes_2024_genre"))
date_naissance: Mapped[date] = mapped_column(Date()) date_naissance: Mapped[date] = mapped_column(Date())
profession: Mapped[str] = mapped_column(String(256)) profession: Mapped[str] = mapped_column(String(256))
code_personnalite: Mapped[str] = mapped_column(Enum(Personnalite)) code_personnalite: Mapped[str] = mapped_column(Enum(Personnalite, name="europeennes_2024_personnalite"))
sortant: Mapped[bool] = mapped_column(Boolean()) sortant: Mapped[bool] = mapped_column(Boolean())
liste: Mapped[ListeEuropeennes2024] = relationship(ListeEuropeennes2024, back_populates="candidats") liste: Mapped[ListeEuropeennes2024] = relationship(ListeEuropeennes2024, back_populates="candidats")

View File

@ -15,7 +15,9 @@ class Region(Base):
departements: Mapped[List["Departement"]] = relationship("Departement", back_populates="region") departements: Mapped[List["Departement"]] = relationship("Departement", back_populates="region")
resultats_legislatives_2022 = relationship("ResultatsRegionLegislatives2022", back_populates="region")
resultats_europeennes_2024 = relationship("ResultatsRegionEuropeennes2024", back_populates="region") resultats_europeennes_2024 = relationship("ResultatsRegionEuropeennes2024", back_populates="region")
resultats_legislatives_2024 = relationship("ResultatsRegionLegislatives2024", back_populates="region")
class Departement(Base): class Departement(Base):
@ -30,7 +32,9 @@ class Departement(Base):
circonscriptions: Mapped[List["Circonscription"]] = relationship("Circonscription", back_populates="departement") circonscriptions: Mapped[List["Circonscription"]] = relationship("Circonscription", back_populates="departement")
communes: Mapped[List["Commune"]] = relationship("Commune", back_populates="departement") communes: Mapped[List["Commune"]] = relationship("Commune", back_populates="departement")
resultats_legislatives_2022 = relationship("ResultatsDepartementLegislatives2022", back_populates="departement")
resultats_europeennes_2024 = relationship("ResultatsDepartementEuropeennes2024", back_populates="departement") resultats_europeennes_2024 = relationship("ResultatsDepartementEuropeennes2024", back_populates="departement")
resultats_legislatives_2024 = relationship("ResultatsDepartementLegislatives2024", back_populates="departement")
class Commune(Base): class Commune(Base):
@ -44,7 +48,9 @@ class Commune(Base):
departement: Mapped[Departement] = relationship(Departement, back_populates="communes") departement: Mapped[Departement] = relationship(Departement, back_populates="communes")
bureaux_vote: Mapped[List["BureauVote"]] = relationship("BureauVote", back_populates="commune") bureaux_vote: Mapped[List["BureauVote"]] = relationship("BureauVote", back_populates="commune")
resultats_legislatives_2022 = relationship("ResultatsCommuneLegislatives2022", back_populates="commune")
resultats_europeennes_2024 = relationship("ResultatsCommuneEuropeennes2024", back_populates="commune") resultats_europeennes_2024 = relationship("ResultatsCommuneEuropeennes2024", back_populates="commune")
resultats_legislatives_2024 = relationship("ResultatsCommuneLegislatives2024", back_populates="commune")
class Circonscription(Base): class Circonscription(Base):
@ -58,8 +64,14 @@ class Circonscription(Base):
departement: Mapped[Departement] = relationship(Departement, back_populates="circonscriptions") departement: Mapped[Departement] = relationship(Departement, back_populates="circonscriptions")
bureaux_vote: Mapped[List["BureauVote"]] = relationship("BureauVote", back_populates="circonscription") bureaux_vote: Mapped[List["BureauVote"]] = relationship("BureauVote", back_populates="circonscription")
candidats_legislatives_2022 = relationship("CandidatLegislatives2022", back_populates="circonscription")
resultats_legislatives_2022 = relationship("ResultatsCirconscriptionLegislatives2022",
back_populates="circonscription")
resultats_europeennes_2024 = relationship("ResultatsCirconscriptionEuropeennes2024", resultats_europeennes_2024 = relationship("ResultatsCirconscriptionEuropeennes2024",
back_populates="circonscription") back_populates="circonscription")
candidats_legislatives_2024 = relationship("CandidatLegislatives2024", back_populates="circonscription")
resultats_legislatives_2024 = relationship("ResultatsCirconscriptionLegislatives2024",
back_populates="circonscription")
class BureauVote(Base): class BureauVote(Base):
@ -76,4 +88,6 @@ class BureauVote(Base):
commune: Mapped[Commune] = relationship(Commune, back_populates="bureaux_vote") commune: Mapped[Commune] = relationship(Commune, back_populates="bureaux_vote")
circonscription: Mapped[Circonscription] = relationship(Circonscription, back_populates="bureaux_vote") circonscription: Mapped[Circonscription] = relationship(Circonscription, back_populates="bureaux_vote")
resultats_legislatives_2022 = relationship("ResultatsBureauVoteLegislatives2022", back_populates="bureau_vote")
resultats_europeennes_2024 = relationship("ResultatsBureauVoteEuropeennes2024", back_populates="bureau_vote") resultats_europeennes_2024 = relationship("ResultatsBureauVoteEuropeennes2024", back_populates="bureau_vote")
resultats_legislatives_2024 = relationship("ResultatsBureauVoteLegislatives2024", back_populates="bureau_vote")

View File

@ -0,0 +1,330 @@
import enum
from datetime import date
from typing import List
from sqlalchemy import Boolean, Date, Enum, ForeignKey, Integer, String
from sqlalchemy.orm import mapped_column, Mapped, relationship
from nupes.models import Base, Region, Departement, Commune, Circonscription
from nupes.models.base import Genre
class BlocLegislatives2022(Base):
__tablename__ = "legislatives_2022_bloc"
id: Mapped[int] = mapped_column(primary_key=True)
nom: Mapped[str] = mapped_column(String(32), unique=True)
couleur: Mapped[str] = mapped_column(String(7))
candidats: Mapped[List["CandidatLegislatives2022"]] = relationship("CandidatLegislatives2022",
back_populates="bloc")
nuances: Mapped[List["NuanceLegislatives2022"]] = relationship(
"NuanceLegislatives2022", back_populates="bloc")
class NuanceLegislatives2022(Base):
__tablename__ = "legislatives_2022_nuance"
code: Mapped[str] = mapped_column(String(8), primary_key=True)
nom: Mapped[str] = mapped_column(String(64), unique=True)
couleur: Mapped[str] = mapped_column(String(7))
bloc_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_bloc.id"))
bloc: Mapped[BlocLegislatives2022] = relationship(BlocLegislatives2022, back_populates="nuances")
candidats: Mapped[List["CandidatLegislatives2022"]] = relationship(
"CandidatLegislatives2022", back_populates="nuance")
resultats_nationaux: Mapped[List["VoixFranceLegislatives2022"]] = relationship(
"VoixFranceLegislatives2022", back_populates="nuance")
resultats_par_region: Mapped[List["VoixRegionLegislatives2022"]] = relationship(
"VoixRegionLegislatives2022", back_populates="nuance")
resultats_par_departement: Mapped[List["VoixDepartementLegislatives2022"]] = relationship(
"VoixDepartementLegislatives2022", back_populates="nuance")
resultats_par_commune: Mapped[List["VoixCommuneLegislatives2022"]] = relationship(
"VoixCommuneLegislatives2022", back_populates="nuance")
class CandidatLegislatives2022(Base):
__tablename__ = "legislatives_2022_candidat"
id: Mapped[int] = mapped_column(primary_key=True)
circonscription_id: Mapped[str] = mapped_column(ForeignKey("circonscription.id"))
numero: Mapped[int] = mapped_column(Integer())
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2022_nuance.code"))
bloc_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_bloc.id"))
nom: Mapped[str] = mapped_column(String(256))
prenom: Mapped[str] = mapped_column(String(256))
sexe: Mapped[str] = mapped_column(Enum(Genre, name="legislatives_2022_genre"))
date_naissance: Mapped[date] = mapped_column(Date())
profession: Mapped[str] = mapped_column(String(256))
sortant: Mapped[bool] = mapped_column(Boolean())
nom_suppleance: Mapped[str] = mapped_column(String(256))
prenom_suppleance: Mapped[str] = mapped_column(String(256))
sexe_suppleance: Mapped[str] = mapped_column(Enum(Genre, name="legislatives_2022_genre"))
date_naissance_suppleance: Mapped[date] = mapped_column(Date())
sortant_suppleance: Mapped[bool] = mapped_column(Boolean())
circonscription: Mapped[Circonscription] = relationship(
"Circonscription", back_populates="candidats_legislatives_2022")
nuance: Mapped[NuanceLegislatives2022] = relationship(NuanceLegislatives2022, back_populates="candidats")
bloc: Mapped[BlocLegislatives2022] = relationship(BlocLegislatives2022, back_populates="candidats")
resultats_par_circonscription: Mapped[List["VoixCirconscriptionLegislatives2022"]] = relationship(
"VoixCirconscriptionLegislatives2022", back_populates="candidat")
resultats_par_bureau_vote: Mapped[List["VoixBureauVoteLegislatives2022"]] = relationship(
"VoixBureauVoteLegislatives2022", back_populates="candidat")
class ResultatsFranceLegislatives2022(Base):
__tablename__ = "legislatives_2022_resultats_france"
id: Mapped[int] = mapped_column(primary_key=True)
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
resultats_regions: Mapped[List["ResultatsRegionLegislatives2022"]] = relationship(
"ResultatsRegionLegislatives2022", back_populates="resultats_france")
voix: Mapped[List["VoixFranceLegislatives2022"]] = relationship(
"VoixFranceLegislatives2022", back_populates="resultats_france")
class ResultatsRegionLegislatives2022(Base):
__tablename__ = "legislatives_2022_resultats_region"
id: Mapped[int] = mapped_column(primary_key=True)
region_id: Mapped[str] = mapped_column(ForeignKey("region.code_insee"))
resultats_france_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_france.id"))
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
region = relationship(Region, back_populates="resultats_legislatives_2022")
resultats_france = relationship(ResultatsFranceLegislatives2022, back_populates="resultats_regions")
resultats_departements: Mapped[List["ResultatsDepartementLegislatives2022"]] = relationship(
"ResultatsDepartementLegislatives2022", back_populates="resultats_region")
voix: Mapped[List["VoixRegionLegislatives2022"]] = relationship(
"VoixRegionLegislatives2022", back_populates="resultats_region")
class ResultatsDepartementLegislatives2022(Base):
__tablename__ = "legislatives_2022_resultats_departement"
id: Mapped[int] = mapped_column(primary_key=True)
dpt_id: Mapped[str] = mapped_column(ForeignKey("departement.code_insee"))
resultats_region_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_region.id"), nullable=True)
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
departement = relationship(Departement, back_populates="resultats_legislatives_2022")
resultats_region = relationship(ResultatsRegionLegislatives2022, back_populates="resultats_departements")
resultats_communes: Mapped[List["ResultatsCommuneLegislatives2022"]] = relationship(
"ResultatsCommuneLegislatives2022", back_populates="resultats_departement")
resultats_circonscriptions: Mapped[List["ResultatsCirconscriptionLegislatives2022"]] = relationship(
"ResultatsCirconscriptionLegislatives2022", back_populates="resultats_departement")
voix: Mapped[List["VoixDepartementLegislatives2022"]] = relationship(
"VoixDepartementLegislatives2022", back_populates="resultats_departement")
class ResultatsCirconscriptionLegislatives2022(Base):
__tablename__ = "legislatives_2022_resultats_circonscription"
id: Mapped[int] = mapped_column(primary_key=True)
circo_id: Mapped[str] = mapped_column(ForeignKey("circonscription.id"))
resultats_departement_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_departement.id"))
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
circonscription = relationship("Circonscription", back_populates="resultats_legislatives_2022")
resultats_departement = relationship(ResultatsDepartementLegislatives2022,
back_populates="resultats_circonscriptions")
resultats_bureaux_vote: Mapped[List["ResultatsBureauVoteLegislatives2022"]] = relationship(
"ResultatsBureauVoteLegislatives2022", back_populates="resultats_circonscription")
voix: Mapped[List["VoixCirconscriptionLegislatives2022"]] = relationship(
"VoixCirconscriptionLegislatives2022", back_populates="resultats_circonscription")
class ResultatsCommuneLegislatives2022(Base):
__tablename__ = "legislatives_2022_resultats_commune"
id: Mapped[int] = mapped_column(primary_key=True)
commune_id: Mapped[str] = mapped_column(ForeignKey("commune.code_insee"))
resultats_dpt_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_departement.id"))
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
commune = relationship(Commune, back_populates="resultats_legislatives_2022")
resultats_departement = relationship(ResultatsDepartementLegislatives2022, back_populates="resultats_communes")
resultats_bureaux_vote: Mapped[List["ResultatsBureauVoteLegislatives2022"]] = relationship(
"ResultatsBureauVoteLegislatives2022", back_populates="resultats_commune")
voix: Mapped[List["VoixCommuneLegislatives2022"]] = relationship(
"VoixCommuneLegislatives2022", back_populates="resultats_commune")
class ResultatsBureauVoteLegislatives2022(Base):
__tablename__ = "legislatives_2022_resultats_bureau_vote"
id: Mapped[int] = mapped_column(primary_key=True)
bv_id: Mapped[str] = mapped_column(ForeignKey("bureau_vote.id"))
resultats_commune_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_commune.id"))
resultats_circo_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_circonscription.id"),
nullable=True)
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
bureau_vote = relationship("BureauVote", back_populates="resultats_legislatives_2022")
resultats_commune = relationship(ResultatsCommuneLegislatives2022, back_populates="resultats_bureaux_vote")
resultats_circonscription = relationship(ResultatsCirconscriptionLegislatives2022,
back_populates="resultats_bureaux_vote")
voix: Mapped[List["VoixBureauVoteLegislatives2022"]] = relationship(
"VoixBureauVoteLegislatives2022", back_populates="resultats_bureau_vote")
class VoixFranceLegislatives2022(Base):
__tablename__ = "legislatives_2022_voix_france"
id: Mapped[int] = mapped_column(primary_key=True)
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2022_nuance.code"))
resultats_france_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_france.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuance: Mapped[NuanceLegislatives2022] = relationship(
NuanceLegislatives2022, back_populates="resultats_nationaux")
resultats_france: Mapped[ResultatsFranceLegislatives2022] = relationship(
ResultatsFranceLegislatives2022, back_populates="voix")
class VoixRegionLegislatives2022(Base):
__tablename__ = "legislatives_2022_voix_region"
id: Mapped[int] = mapped_column(primary_key=True)
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2022_nuance.code"))
resultats_region_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_region.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuance: Mapped[NuanceLegislatives2022] = relationship(
NuanceLegislatives2022, back_populates="resultats_par_region")
resultats_region: Mapped[ResultatsRegionLegislatives2022] = relationship(
ResultatsRegionLegislatives2022, back_populates="voix")
class VoixDepartementLegislatives2022(Base):
__tablename__ = "legislatives_2022_voix_departement"
id: Mapped[int] = mapped_column(primary_key=True)
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2022_nuance.code"))
resultats_departement_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_departement.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuance: Mapped[NuanceLegislatives2022] = relationship(
NuanceLegislatives2022, back_populates="resultats_par_departement")
resultats_departement: Mapped[ResultatsDepartementLegislatives2022] = relationship(
ResultatsDepartementLegislatives2022, back_populates="voix")
class VoixCirconscriptionLegislatives2022(Base):
__tablename__ = "legislatives_2022_voix_circonscription"
id: Mapped[int] = mapped_column(primary_key=True)
candidat_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_candidat.id"))
resultats_circonscription_id: Mapped[int] = mapped_column(
ForeignKey("legislatives_2022_resultats_circonscription.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
candidat: Mapped[CandidatLegislatives2022] = relationship(
CandidatLegislatives2022, back_populates="resultats_par_circonscription")
resultats_circonscription: Mapped[ResultatsCirconscriptionLegislatives2022] = relationship(
ResultatsCirconscriptionLegislatives2022, back_populates="voix")
class VoixCommuneLegislatives2022(Base):
__tablename__ = "legislatives_2022_voix_commune"
id: Mapped[int] = mapped_column(primary_key=True)
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2022_nuance.code"))
resultats_commune_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_commune.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuance: Mapped[NuanceLegislatives2022] = relationship(
NuanceLegislatives2022, back_populates="resultats_par_commune")
resultats_commune: Mapped[ResultatsCommuneLegislatives2022] = relationship(
ResultatsCommuneLegislatives2022, back_populates="voix")
class VoixBureauVoteLegislatives2022(Base):
__tablename__ = "legislatives_2022_voix_bureau_vote"
id: Mapped[int] = mapped_column(primary_key=True)
candidat_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_candidat.id"))
resultats_bureau_vote_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2022_resultats_bureau_vote.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
candidat: Mapped[CandidatLegislatives2022] = relationship(CandidatLegislatives2022,
back_populates="resultats_par_bureau_vote")
resultats_bureau_vote: Mapped[ResultatsBureauVoteLegislatives2022] = relationship(
ResultatsBureauVoteLegislatives2022, back_populates="voix")

View File

@ -0,0 +1,329 @@
import enum
from datetime import date
from typing import List
from sqlalchemy import Boolean, Date, Enum, ForeignKey, Integer, String
from sqlalchemy.orm import mapped_column, Mapped, relationship
from nupes.models import Base, Region, Departement, Commune, Circonscription, Genre
class BlocLegislatives2024(Base):
__tablename__ = "legislatives_2024_bloc"
id: Mapped[int] = mapped_column(primary_key=True)
nom: Mapped[str] = mapped_column(String(32), unique=True)
couleur: Mapped[str] = mapped_column(String(7))
candidats: Mapped[List["CandidatLegislatives2024"]] = relationship("CandidatLegislatives2024",
back_populates="bloc")
nuances: Mapped[List["NuanceLegislatives2024"]] = relationship(
"NuanceLegislatives2024", back_populates="bloc")
class NuanceLegislatives2024(Base):
__tablename__ = "legislatives_2024_nuance"
code: Mapped[str] = mapped_column(String(8), primary_key=True)
nom: Mapped[str] = mapped_column(String(64), unique=True)
couleur: Mapped[str] = mapped_column(String(7))
bloc_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_bloc.id"))
bloc: Mapped[BlocLegislatives2024] = relationship(BlocLegislatives2024, back_populates="nuances")
candidats: Mapped[List["CandidatLegislatives2024"]] = relationship(
"CandidatLegislatives2024", back_populates="nuance")
resultats_nationaux: Mapped[List["VoixFranceLegislatives2024"]] = relationship(
"VoixFranceLegislatives2024", back_populates="nuance")
resultats_par_region: Mapped[List["VoixRegionLegislatives2024"]] = relationship(
"VoixRegionLegislatives2024", back_populates="nuance")
resultats_par_departement: Mapped[List["VoixDepartementLegislatives2024"]] = relationship(
"VoixDepartementLegislatives2024", back_populates="nuance")
resultats_par_commune: Mapped[List["VoixCommuneLegislatives2024"]] = relationship(
"VoixCommuneLegislatives2024", back_populates="nuance")
class CandidatLegislatives2024(Base):
__tablename__ = "legislatives_2024_candidat"
id: Mapped[int] = mapped_column(primary_key=True)
circonscription_id: Mapped[str] = mapped_column(ForeignKey("circonscription.id"))
numero: Mapped[int] = mapped_column(Integer())
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2024_nuance.code"))
bloc_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_bloc.id"))
nom: Mapped[str] = mapped_column(String(256))
prenom: Mapped[str] = mapped_column(String(256))
sexe: Mapped[str] = mapped_column(Enum(Genre, name="legislatives_2024_genre"))
date_naissance: Mapped[date] = mapped_column(Date())
profession: Mapped[str] = mapped_column(String(256))
sortant: Mapped[bool] = mapped_column(Boolean())
nom_suppleance: Mapped[str] = mapped_column(String(256))
prenom_suppleance: Mapped[str] = mapped_column(String(256))
sexe_suppleance: Mapped[str] = mapped_column(Enum(Genre, name="legislatives_2024_genre_suppl"))
date_naissance_suppleance: Mapped[date] = mapped_column(Date())
sortant_suppleance: Mapped[bool] = mapped_column(Boolean())
circonscription: Mapped[Circonscription] = relationship(
"Circonscription", back_populates="candidats_legislatives_2024")
nuance: Mapped[NuanceLegislatives2024] = relationship(NuanceLegislatives2024, back_populates="candidats")
bloc: Mapped[BlocLegislatives2024] = relationship(BlocLegislatives2024, back_populates="candidats")
resultats_par_circonscription: Mapped[List["VoixCirconscriptionLegislatives2024"]] = relationship(
"VoixCirconscriptionLegislatives2024", back_populates="candidat")
resultats_par_bureau_vote: Mapped[List["VoixBureauVoteLegislatives2024"]] = relationship(
"VoixBureauVoteLegislatives2024", back_populates="candidat")
class ResultatsFranceLegislatives2024(Base):
__tablename__ = "legislatives_2024_resultats_france"
id: Mapped[int] = mapped_column(primary_key=True)
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
resultats_regions: Mapped[List["ResultatsRegionLegislatives2024"]] = relationship(
"ResultatsRegionLegislatives2024", back_populates="resultats_france")
voix: Mapped[List["VoixFranceLegislatives2024"]] = relationship(
"VoixFranceLegislatives2024", back_populates="resultats_france")
class ResultatsRegionLegislatives2024(Base):
__tablename__ = "legislatives_2024_resultats_region"
id: Mapped[int] = mapped_column(primary_key=True)
region_id: Mapped[str] = mapped_column(ForeignKey("region.code_insee"))
resultats_france_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_france.id"))
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
region = relationship(Region, back_populates="resultats_legislatives_2024")
resultats_france = relationship(ResultatsFranceLegislatives2024, back_populates="resultats_regions")
resultats_departements: Mapped[List["ResultatsDepartementLegislatives2024"]] = relationship(
"ResultatsDepartementLegislatives2024", back_populates="resultats_region")
voix: Mapped[List["VoixRegionLegislatives2024"]] = relationship(
"VoixRegionLegislatives2024", back_populates="resultats_region")
class ResultatsDepartementLegislatives2024(Base):
__tablename__ = "legislatives_2024_resultats_departement"
id: Mapped[int] = mapped_column(primary_key=True)
dpt_id: Mapped[str] = mapped_column(ForeignKey("departement.code_insee"))
resultats_region_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_region.id"), nullable=True)
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
departement = relationship(Departement, back_populates="resultats_legislatives_2024")
resultats_region = relationship(ResultatsRegionLegislatives2024, back_populates="resultats_departements")
resultats_communes: Mapped[List["ResultatsCommuneLegislatives2024"]] = relationship(
"ResultatsCommuneLegislatives2024", back_populates="resultats_departement")
resultats_circonscriptions: Mapped[List["ResultatsCirconscriptionLegislatives2024"]] = relationship(
"ResultatsCirconscriptionLegislatives2024", back_populates="resultats_departement")
voix: Mapped[List["VoixDepartementLegislatives2024"]] = relationship(
"VoixDepartementLegislatives2024", back_populates="resultats_departement")
class ResultatsCirconscriptionLegislatives2024(Base):
__tablename__ = "legislatives_2024_resultats_circonscription"
id: Mapped[int] = mapped_column(primary_key=True)
circo_id: Mapped[str] = mapped_column(ForeignKey("circonscription.id"))
resultats_departement_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_departement.id"))
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
circonscription = relationship("Circonscription", back_populates="resultats_legislatives_2024")
resultats_departement = relationship(ResultatsDepartementLegislatives2024,
back_populates="resultats_circonscriptions")
resultats_bureaux_vote: Mapped[List["ResultatsBureauVoteLegislatives2024"]] = relationship(
"ResultatsBureauVoteLegislatives2024", back_populates="resultats_circonscription")
voix: Mapped[List["VoixCirconscriptionLegislatives2024"]] = relationship(
"VoixCirconscriptionLegislatives2024", back_populates="resultats_circonscription")
class ResultatsCommuneLegislatives2024(Base):
__tablename__ = "legislatives_2024_resultats_commune"
id: Mapped[int] = mapped_column(primary_key=True)
commune_id: Mapped[str] = mapped_column(ForeignKey("commune.code_insee"))
resultats_dpt_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_departement.id"))
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
commune = relationship(Commune, back_populates="resultats_legislatives_2024")
resultats_departement = relationship(ResultatsDepartementLegislatives2024, back_populates="resultats_communes")
resultats_bureaux_vote: Mapped[List["ResultatsBureauVoteLegislatives2024"]] = relationship(
"ResultatsBureauVoteLegislatives2024", back_populates="resultats_commune")
voix: Mapped[List["VoixCommuneLegislatives2024"]] = relationship(
"VoixCommuneLegislatives2024", back_populates="resultats_commune")
class ResultatsBureauVoteLegislatives2024(Base):
__tablename__ = "legislatives_2024_resultats_bureau_vote"
id: Mapped[int] = mapped_column(primary_key=True)
bv_id: Mapped[str] = mapped_column(ForeignKey("bureau_vote.id"))
resultats_commune_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_commune.id"))
resultats_circo_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_circonscription.id"),
nullable=True)
inscrits_t1: Mapped[int] = mapped_column(Integer(), default=0)
votants_t1: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t1: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t1: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t1: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t1: Mapped[int] = mapped_column(Integer(), default=0)
inscrits_t2: Mapped[int] = mapped_column(Integer(), default=0)
votants_t2: Mapped[int] = mapped_column(Integer(), default=0)
abstentions_t2: Mapped[int] = mapped_column(Integer(), default=0)
exprimes_t2: Mapped[int] = mapped_column(Integer(), default=0)
blancs_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuls_t2: Mapped[int] = mapped_column(Integer(), default=0)
bureau_vote = relationship("BureauVote", back_populates="resultats_legislatives_2024")
resultats_commune = relationship(ResultatsCommuneLegislatives2024, back_populates="resultats_bureaux_vote")
resultats_circonscription = relationship(ResultatsCirconscriptionLegislatives2024,
back_populates="resultats_bureaux_vote")
voix: Mapped[List["VoixBureauVoteLegislatives2024"]] = relationship(
"VoixBureauVoteLegislatives2024", back_populates="resultats_bureau_vote")
class VoixFranceLegislatives2024(Base):
__tablename__ = "legislatives_2024_voix_france"
id: Mapped[int] = mapped_column(primary_key=True)
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2024_nuance.code"))
resultats_france_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_france.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuance: Mapped[NuanceLegislatives2024] = relationship(
NuanceLegislatives2024, back_populates="resultats_nationaux")
resultats_france: Mapped[ResultatsFranceLegislatives2024] = relationship(
ResultatsFranceLegislatives2024, back_populates="voix")
class VoixRegionLegislatives2024(Base):
__tablename__ = "legislatives_2024_voix_region"
id: Mapped[int] = mapped_column(primary_key=True)
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2024_nuance.code"))
resultats_region_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_region.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuance: Mapped[NuanceLegislatives2024] = relationship(
NuanceLegislatives2024, back_populates="resultats_par_region")
resultats_region: Mapped[ResultatsRegionLegislatives2024] = relationship(
ResultatsRegionLegislatives2024, back_populates="voix")
class VoixDepartementLegislatives2024(Base):
__tablename__ = "legislatives_2024_voix_departement"
id: Mapped[int] = mapped_column(primary_key=True)
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2024_nuance.code"))
resultats_departement_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_departement.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuance: Mapped[NuanceLegislatives2024] = relationship(
NuanceLegislatives2024, back_populates="resultats_par_departement")
resultats_departement: Mapped[ResultatsDepartementLegislatives2024] = relationship(
ResultatsDepartementLegislatives2024, back_populates="voix")
class VoixCirconscriptionLegislatives2024(Base):
__tablename__ = "legislatives_2024_voix_circonscription"
id: Mapped[int] = mapped_column(primary_key=True)
candidat_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_candidat.id"))
resultats_circonscription_id: Mapped[int] = mapped_column(
ForeignKey("legislatives_2024_resultats_circonscription.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
candidat: Mapped[CandidatLegislatives2024] = relationship(
CandidatLegislatives2024, back_populates="resultats_par_circonscription")
resultats_circonscription: Mapped[ResultatsCirconscriptionLegislatives2024] = relationship(
ResultatsCirconscriptionLegislatives2024, back_populates="voix")
class VoixCommuneLegislatives2024(Base):
__tablename__ = "legislatives_2024_voix_commune"
id: Mapped[int] = mapped_column(primary_key=True)
nuance_id: Mapped[str] = mapped_column(ForeignKey("legislatives_2024_nuance.code"))
resultats_commune_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_commune.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
nuance: Mapped[NuanceLegislatives2024] = relationship(
NuanceLegislatives2024, back_populates="resultats_par_commune")
resultats_commune: Mapped[ResultatsCommuneLegislatives2024] = relationship(
ResultatsCommuneLegislatives2024, back_populates="voix")
class VoixBureauVoteLegislatives2024(Base):
__tablename__ = "legislatives_2024_voix_bureau_vote"
id: Mapped[int] = mapped_column(primary_key=True)
candidat_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_candidat.id"))
resultats_bureau_vote_id: Mapped[int] = mapped_column(ForeignKey("legislatives_2024_resultats_bureau_vote.id"))
voix_t1: Mapped[int] = mapped_column(Integer(), default=0)
voix_t2: Mapped[int] = mapped_column(Integer(), default=0)
candidat: Mapped[CandidatLegislatives2024] = relationship(CandidatLegislatives2024,
back_populates="resultats_par_bureau_vote")
resultats_bureau_vote: Mapped[ResultatsBureauVoteLegislatives2024] = relationship(
ResultatsBureauVoteLegislatives2024, back_populates="voix")

View File

@ -5,10 +5,10 @@ from sqlalchemy import Engine, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from tqdm import tqdm from tqdm import tqdm
from nupes.models.geographie import Region, Departement, Commune, Circonscription, BureauVote from nupes.models.geographie import Circonscription, BureauVote
from nupes.models.europeennes2024 import * from nupes.models.europeennes2024 import *
DATA_DIR = Path(__file__).parent.parent.parent / 'data' DATA_DIR = Path(__file__).parent.parent.parent.parent / 'data'
def exporter_listes(engine: Engine, verbose: bool = False) -> None: def exporter_listes(engine: Engine, verbose: bool = False) -> None:
@ -17,7 +17,11 @@ def exporter_listes(engine: Engine, verbose: bool = False) -> None:
blocs_json = [] blocs_json = []
for bloc in blocs: for bloc in blocs:
bloc_json = {'id': bloc.id, 'nom': bloc.nom, 'couleur': bloc.couleur} bloc_json = {
'id': bloc.id,
'nom': bloc.nom,
'couleur': bloc.couleur,
}
blocs_json.append(bloc_json) blocs_json.append(bloc_json)
file = DATA_DIR / "resultats" / "europeennes" / "2024" / "blocs.json" file = DATA_DIR / "resultats" / "europeennes" / "2024" / "blocs.json"
@ -31,7 +35,11 @@ def exporter_listes(engine: Engine, verbose: bool = False) -> None:
nuances_json = [] nuances_json = []
for nuance in nuances: for nuance in nuances:
nuance_json = {'code': nuance.code, 'nom': nuance.nom, 'couleur': nuance.couleur} nuance_json = {
'code': nuance.code,
'nom': nuance.nom,
'couleur': nuance.couleur,
}
nuances_json.append(nuance_json) nuances_json.append(nuance_json)
file = DATA_DIR / "resultats" / "europeennes" / "2024" / "nuances.json" file = DATA_DIR / "resultats" / "europeennes" / "2024" / "nuances.json"
@ -46,13 +54,25 @@ def exporter_listes(engine: Engine, verbose: bool = False) -> None:
for liste in listes: for liste in listes:
candidats = [ candidats = [
{'ordre': candidat.ordre, 'nom': candidat.nom, 'prenom': candidat.prenom, 'sexe': candidat.sexe.value, {
'date_naissance': candidat.date_naissance.isoformat(), 'profession': candidat.profession, 'ordre': candidat.ordre,
'code_personnalite': candidat.code_personnalite.value, 'sortant': candidat.sortant} 'nom': candidat.nom,
'prenom': candidat.prenom,
'sexe': candidat.sexe.value,
'date_naissance': candidat.date_naissance.isoformat(),
'profession': candidat.profession,
'code_personnalite': candidat.code_personnalite.value,
'sortant': candidat.sortant
}
for candidat in liste.candidats for candidat in liste.candidats
] ]
liste_json = {'numero': liste.numero, 'nom': liste.nom, 'nuance': liste.nuance_id, liste_json = {
'bloc': liste.bloc.nom, 'candidats': candidats} 'numero': liste.numero,
'nom': liste.nom,
'nuance': liste.nuance_id,
'bloc': liste.bloc.nom,
'candidats': candidats,
}
listes_json.append(liste_json) listes_json.append(liste_json)
file = DATA_DIR / "resultats" / "europeennes" / "2024" / "listes.json" file = DATA_DIR / "resultats" / "europeennes" / "2024" / "listes.json"
@ -71,22 +91,25 @@ def exporter_resultats_france(engine: Engine, verbose: bool = False) -> None:
session.add(resultats_france) session.add(resultats_france)
resultats_dict = { resultats_dict = {
'france': { 'zone': {
'type': "france",
'regions': [reg.code_insee for reg in session.execute(select(Region)).scalars().all()], 'regions': [reg.code_insee for reg in session.execute(select(Region)).scalars().all()],
'departements': [dpt.code_insee for dpt in session.execute(select(Departement)).scalars().all()], 'departements': [dpt.code_insee for dpt in session.execute(select(Departement)).scalars().all()],
'circonscriptions': [circo.id for circo in session.execute(select(Circonscription)).scalars().all()], 'circonscriptions': [circo.id for circo in session.execute(select(Circonscription)).scalars().all()],
},
"inscrits": resultats_france.inscrits,
"votants": resultats_france.votants,
"abstentions": resultats_france.abstentions,
"exprimes": resultats_france.exprimes,
"blancs": resultats_france.blancs,
"nuls": resultats_france.nuls,
'geometry': {}, 'geometry': {},
},
'tour1': {
'inscrits': resultats_france.inscrits,
'votants': resultats_france.votants,
'abstentions': resultats_france.abstentions,
'exprimes': resultats_france.exprimes,
'blancs': resultats_france.blancs,
'nuls': resultats_france.nuls,
},
} }
resultats_listes = {} resultats_listes = {}
resultats_dict['voix'] = resultats_listes resultats_dict['tour1']['voix'] = resultats_listes
for voix_liste in resultats_france.voix_listes: for voix_liste in resultats_france.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix resultats_listes[voix_liste.liste.numero] = voix_liste.voix
@ -107,12 +130,17 @@ def exporter_resultats_regions(engine: Engine, verbose: bool = False) -> None:
regions_iterator = tqdm(regions, desc="Régions") if verbose else regions regions_iterator = tqdm(regions, desc="Régions") if verbose else regions
for region in regions_iterator: for region in regions_iterator:
region_json = {'code_insee': region.code_insee, 'nom': region.libelle, region_json = {
'type': "region",
'code_insee': region.code_insee, 'nom': region.libelle,
'departements': [dpt.code_insee for dpt in region.departements], 'departements': [dpt.code_insee for dpt in region.departements],
'circonscriptions': 'circonscriptions': [
[circo.id for circo in session.execute( circo.id for circo in session.execute(
select(Circonscription).join(Departement).filter_by(region_code=region.code_insee)) select(Circonscription).join(Departement).filter_by(region_code=region.code_insee))
.scalars().all()]} .scalars().all()
],
'geometry': region.geometry,
}
regions_json.append(region_json) regions_json.append(region_json)
resultats_region = session.execute(select(ResultatsRegionEuropeennes2024) resultats_region = session.execute(select(ResultatsRegionEuropeennes2024)
@ -124,18 +152,19 @@ def exporter_resultats_regions(engine: Engine, verbose: bool = False) -> None:
session.add(resultats_region) session.add(resultats_region)
resultats_dict = { resultats_dict = {
"inscrits": resultats_region.inscrits, 'zone': region_json,
"votants": resultats_region.votants, 'tour1': {
"abstentions": resultats_region.abstentions, 'inscrits': resultats_region.inscrits,
"exprimes": resultats_region.exprimes, 'votants': resultats_region.votants,
"blancs": resultats_region.blancs, 'abstentions': resultats_region.abstentions,
"nuls": resultats_region.nuls, 'exprimes': resultats_region.exprimes,
'region': region_json, 'blancs': resultats_region.blancs,
'geometry': region.geometry, 'nuls': resultats_region.nuls,
},
} }
resultats_listes = {} resultats_listes = {}
resultats_dict['voix'] = resultats_listes resultats_dict['tour1']['voix'] = resultats_listes
for voix_liste in resultats_region.voix_listes: for voix_liste in resultats_region.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix resultats_listes[voix_liste.liste.numero] = voix_liste.voix
@ -163,10 +192,15 @@ def exporter_resultats_departements(engine: Engine, verbose: bool = False) -> No
iterator = tqdm(departements, desc="Départements") if verbose else departements iterator = tqdm(departements, desc="Départements") if verbose else departements
for departement in iterator: for departement in iterator:
departement_json = {'code_insee': departement.code_insee, 'nom': departement.libelle, departement_json = {
'type': "departement",
'code_insee': departement.code_insee,
'nom': departement.libelle,
'region': departement.region_code, 'region': departement.region_code,
'circonscriptions': [circo.id for circo in departement.circonscriptions], 'circonscriptions': [circo.id for circo in departement.circonscriptions],
'communes': [commune.code_insee for commune in departement.communes]} 'communes': [commune.code_insee for commune in departement.communes],
'geometry': departement.geometry,
}
departements_json.append(departement_json) departements_json.append(departement_json)
resultats_departement = session.execute( resultats_departement = session.execute(
@ -180,18 +214,19 @@ def exporter_resultats_departements(engine: Engine, verbose: bool = False) -> No
session.add(resultats_departement) session.add(resultats_departement)
resultats_dict = { resultats_dict = {
"inscrits": resultats_departement.inscrits, 'zone': departement_json,
"votants": resultats_departement.votants, 'tour1': {
"abstentions": resultats_departement.abstentions, 'inscrits': resultats_departement.inscrits,
"exprimes": resultats_departement.exprimes, 'votants': resultats_departement.votants,
"blancs": resultats_departement.blancs, 'abstentions': resultats_departement.abstentions,
"nuls": resultats_departement.nuls, 'exprimes': resultats_departement.exprimes,
'departement': departement_json, 'blancs': resultats_departement.blancs,
'geometry': departement.geometry, 'nuls': resultats_departement.nuls,
},
} }
resultats_listes = {} resultats_listes = {}
resultats_dict['voix'] = resultats_listes resultats_dict['tour1']['voix'] = resultats_listes
for voix_liste in resultats_departement.voix_listes: for voix_liste in resultats_departement.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix resultats_listes[voix_liste.liste.numero] = voix_liste.voix
@ -219,9 +254,14 @@ def exporter_resultats_circonscriptions(engine: Engine, verbose: bool = False) -
iterator = tqdm(circonscriptions, desc="Circonscriptions") if verbose else circonscriptions iterator = tqdm(circonscriptions, desc="Circonscriptions") if verbose else circonscriptions
for circonscription in iterator: for circonscription in iterator:
circonscription_json = {'id': circonscription.id, 'departement': circonscription.departement_code, circonscription_json = {
'type': "circonscription",
'id': circonscription.id,
'departement': circonscription.departement_code,
'numero': circonscription.numero, 'numero': circonscription.numero,
'bureaux_vote': [bv.id for bv in circonscription.bureaux_vote]} 'bureaux_vote': [bv.id for bv in circonscription.bureaux_vote],
'geometry': circonscription.geometry,
}
circonscriptions_json.append(circonscription_json) circonscriptions_json.append(circonscription_json)
resultats_circonscription = session.execute( resultats_circonscription = session.execute(
@ -236,18 +276,19 @@ def exporter_resultats_circonscriptions(engine: Engine, verbose: bool = False) -
session.add(resultats_circonscription) session.add(resultats_circonscription)
resultats_dict = { resultats_dict = {
"inscrits": resultats_circonscription.inscrits, 'zone': circonscription_json,
"votants": resultats_circonscription.votants, 'tour1': {
"abstentions": resultats_circonscription.abstentions, 'inscrits': resultats_circonscription.inscrits,
"exprimes": resultats_circonscription.exprimes, 'votants': resultats_circonscription.votants,
"blancs": resultats_circonscription.blancs, 'abstentions': resultats_circonscription.abstentions,
"nuls": resultats_circonscription.nuls, 'exprimes': resultats_circonscription.exprimes,
'circonscription': circonscription_json, 'blancs': resultats_circonscription.blancs,
'geometry': circonscription.geometry, 'nuls': resultats_circonscription.nuls,
},
} }
resultats_listes = {} resultats_listes = {}
resultats_dict['voix'] = resultats_listes resultats_dict['tour1']['voix'] = resultats_listes
for voix_liste in resultats_circonscription.voix_listes: for voix_liste in resultats_circonscription.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix resultats_listes[voix_liste.liste.numero] = voix_liste.voix
@ -276,9 +317,14 @@ def exporter_resultats_communes(engine: Engine, verbose: bool = False) -> None:
iterator = tqdm(communes, desc="Communes") if verbose else communes iterator = tqdm(communes, desc="Communes") if verbose else communes
for commune in iterator: for commune in iterator:
commune_json = {'code_insee': commune.code_insee, 'nom': commune.libelle, commune_json = {
'type': "commune",
'code_insee': commune.code_insee,
'nom': commune.libelle,
'departement': commune.departement_code, 'departement': commune.departement_code,
'bureaux_vote': [bv.id for bv in commune.bureaux_vote]} 'bureaux_vote': [bv.id for bv in commune.bureaux_vote],
'geometry': commune.geometry,
}
communes_json.append(commune_json) communes_json.append(commune_json)
resultats_commune = session.execute( resultats_commune = session.execute(
@ -291,18 +337,19 @@ def exporter_resultats_communes(engine: Engine, verbose: bool = False) -> None:
session.add(resultats_commune) session.add(resultats_commune)
resultats_dict = { resultats_dict = {
"inscrits": resultats_commune.inscrits, 'zone': commune_json,
"votants": resultats_commune.votants, 'tour1': {
"abstentions": resultats_commune.abstentions, 'inscrits': resultats_commune.inscrits,
"exprimes": resultats_commune.exprimes, 'votants': resultats_commune.votants,
"blancs": resultats_commune.blancs, 'abstentions': resultats_commune.abstentions,
"nuls": resultats_commune.nuls, 'exprimes': resultats_commune.exprimes,
'commune': commune_json, 'blancs': resultats_commune.blancs,
'geometry': commune.geometry, 'nuls': resultats_commune.nuls,
},
} }
resultats_listes = {} resultats_listes = {}
resultats_dict['voix'] = resultats_listes resultats_dict['tour1']['voix'] = resultats_listes
for voix_liste in resultats_commune.voix_listes: for voix_liste in resultats_commune.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix resultats_listes[voix_liste.liste.numero] = voix_liste.voix
@ -330,10 +377,14 @@ def exporter_resultats_bureaux_vote(engine: Engine, verbose: bool = False) -> No
iterator = tqdm(bureaux_vote, desc="Bureaux de vote") if verbose else bureaux_vote iterator = tqdm(bureaux_vote, desc="Bureaux de vote") if verbose else bureaux_vote
for bureau_vote in iterator: for bureau_vote in iterator:
bureau_vote_json = {'id': bureau_vote.id, bureau_vote_json = {
'type': "bureau_vote",
'id': bureau_vote.id,
'libelle': bureau_vote.libelle, 'libelle': bureau_vote.libelle,
'commune': bureau_vote.commune_code, 'commune': bureau_vote.commune_code,
'circonscription': bureau_vote.circo_code} 'circonscription': bureau_vote.circo_code,
'geometry': bureau_vote.geometry,
}
bureaux_vote_json.append(bureau_vote_json) bureaux_vote_json.append(bureau_vote_json)
resultats_bureau_vote = session.execute( resultats_bureau_vote = session.execute(
@ -346,18 +397,19 @@ def exporter_resultats_bureaux_vote(engine: Engine, verbose: bool = False) -> No
session.add(resultats_bureau_vote) session.add(resultats_bureau_vote)
resultats_dict = { resultats_dict = {
"inscrits": resultats_bureau_vote.inscrits, 'zone': bureau_vote_json,
"votants": resultats_bureau_vote.votants, 'tour1': {
"abstentions": resultats_bureau_vote.abstentions, 'inscrits': resultats_bureau_vote.inscrits,
"exprimes": resultats_bureau_vote.exprimes, 'votants': resultats_bureau_vote.votants,
"blancs": resultats_bureau_vote.blancs, 'abstentions': resultats_bureau_vote.abstentions,
"nuls": resultats_bureau_vote.nuls, 'exprimes': resultats_bureau_vote.exprimes,
'bureau_vote': bureau_vote_json, 'blancs': resultats_bureau_vote.blancs,
'geometry': bureau_vote.geometry, 'nuls': resultats_bureau_vote.nuls,
},
} }
resultats_listes = {} resultats_listes = {}
resultats_dict['voix'] = resultats_listes resultats_dict['tour1']['voix'] = resultats_listes
for voix_liste in resultats_bureau_vote.voix_listes: for voix_liste in resultats_bureau_vote.voix_listes:
resultats_listes[voix_liste.liste.numero] = voix_liste.voix resultats_listes[voix_liste.liste.numero] = voix_liste.voix

View File

@ -5,6 +5,7 @@ from sqlalchemy import Engine, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from nupes.cache import get_file from nupes.cache import get_file
from nupes.models import Genre, Personnalite
from nupes.models.europeennes2024 import BlocEuropeennes2024, NuanceEuropeennes2024, ListeEuropeennes2024, \ from nupes.models.europeennes2024 import BlocEuropeennes2024, NuanceEuropeennes2024, ListeEuropeennes2024, \
CandidatEuropeennes2024 CandidatEuropeennes2024
@ -148,10 +149,10 @@ def importer_candidats(engine: Engine, verbose: bool = False) -> None:
candidat.liste_id = liste.id candidat.liste_id = liste.id
candidat.nom = line['Nom sur le bulletin de vote'] candidat.nom = line['Nom sur le bulletin de vote']
candidat.prenom = line['Prénom sur le bulletin de vote'] candidat.prenom = line['Prénom sur le bulletin de vote']
candidat.sexe = CandidatEuropeennes2024.Genre(line['Sexe']) candidat.sexe = Genre(line['Sexe'])
candidat.date_naissance = datetime.datetime.strptime(line['Date de naissance'], "%d/%m/%Y").date() candidat.date_naissance = datetime.datetime.strptime(line['Date de naissance'], "%d/%m/%Y").date()
candidat.profession = line['Profession'] candidat.profession = line['Profession']
candidat.code_personnalite = CandidatEuropeennes2024.Personnalite(line['Code personnalité']) candidat.code_personnalite = Personnalite(line['Code personnalité'])
candidat.sortant = line['Sortant'] == "OUI" candidat.sortant = line['Sortant'] == "OUI"
else: else:
candidat = CandidatEuropeennes2024( candidat = CandidatEuropeennes2024(
@ -159,10 +160,10 @@ def importer_candidats(engine: Engine, verbose: bool = False) -> None:
ordre=int(line['Ordre']), ordre=int(line['Ordre']),
nom=line['Nom sur le bulletin de vote'], nom=line['Nom sur le bulletin de vote'],
prenom=line['Prénom sur le bulletin de vote'], prenom=line['Prénom sur le bulletin de vote'],
sexe=CandidatEuropeennes2024.Genre(line['Sexe']).name, sexe=Genre(line['Sexe']).name,
date_naissance=datetime.datetime.strptime(line['Date de naissance'], "%d/%m/%Y").date(), date_naissance=datetime.datetime.strptime(line['Date de naissance'], "%d/%m/%Y").date(),
profession=line['Profession'], profession=line['Profession'],
code_personnalite=CandidatEuropeennes2024.Personnalite(line['Code personnalité']).name, code_personnalite=Personnalite(line['Code personnalité']).name,
sortant=line['Sortant'] == "OUI", sortant=line['Sortant'] == "OUI",
) )
session.add(candidat) session.add(candidat)

View File

@ -11,7 +11,7 @@ from nupes.models.europeennes2024 import *
def importer_resultats_bv(engine: Engine, verbose: bool = False) -> None: def importer_resultats_bv(engine: Engine, verbose: bool = False) -> None:
file = get_file("https://www.data.gouv.fr/fr/datasets/r/cc1883d9-1265-4365-b754-fb6aef22d82e", file = get_file("https://www.data.gouv.fr/fr/datasets/r/cc1883d9-1265-4365-b754-fb6aef22d82e",
"resultats-europeennes-par-bureau-de-vote.csv") "resultats-europeennes-2024-par-bureau-de-vote.csv")
with file.open('r') as f: with file.open('r') as f:
reader = DictReader(f, delimiter=';') reader = DictReader(f, delimiter=';')
@ -20,7 +20,8 @@ def importer_resultats_bv(engine: Engine, verbose: bool = False) -> None:
com_code = str(row['Code commune']).zfill(5) com_code = str(row['Code commune']).zfill(5)
bv_code = row['Code BV'] bv_code = row['Code BV']
if com_code.startswith("987"): # Les communes de Polynésie française ne sont pas importées if com_code.startswith("987") or com_code.startswith("988"):
# Les communes de Polynésie française ne sont pas importées
continue continue
if com_code == "60694": if com_code == "60694":
@ -111,7 +112,7 @@ def importer_resultats_bv(engine: Engine, verbose: bool = False) -> None:
def importer_resultats_commune(engine: Engine, verbose: bool = False) -> None: def importer_resultats_commune(engine: Engine, verbose: bool = False) -> None:
file = get_file("https://www.data.gouv.fr/fr/datasets/r/6a782ef9-8ad6-4e66-832d-338b1041a42d", file = get_file("https://www.data.gouv.fr/fr/datasets/r/6a782ef9-8ad6-4e66-832d-338b1041a42d",
"resultats-europeennes-par-commune.csv") "resultats-europeennes-2024-par-commune.csv")
with file.open('r') as f: with file.open('r') as f:
reader = DictReader(f, delimiter=';') reader = DictReader(f, delimiter=';')
@ -123,7 +124,8 @@ def importer_resultats_commune(engine: Engine, verbose: bool = False) -> None:
if dpt_code == "ZX": # Saint-Martin/Saint-Barthélémy if dpt_code == "ZX": # Saint-Martin/Saint-Barthélémy
dpt_code = "977" dpt_code = "977"
if dpt_code == "987": # Les communes de Polynésie française ne sont pas importées if dpt_code == "977" or dpt_code == "987" or dpt_code == "988":
# Les communes de Polynésie française ne sont pas importées
continue continue
if com_code == "60694": if com_code == "60694":
@ -195,7 +197,7 @@ def importer_resultats_commune(engine: Engine, verbose: bool = False) -> None:
def importer_resultats_circo(engine: Engine, verbose: bool = False) -> None: def importer_resultats_circo(engine: Engine, verbose: bool = False) -> None:
file = get_file("https://www.data.gouv.fr/fr/datasets/r/ee37cbef-3d2a-4efe-a395-530b85a63028", file = get_file("https://www.data.gouv.fr/fr/datasets/r/ee37cbef-3d2a-4efe-a395-530b85a63028",
"resultats-europeennes-par-circonscription.csv") "resultats-europeennes-2024-par-circonscription.csv")
with file.open('r') as f: with file.open('r') as f:
reader = DictReader(f, delimiter=';') reader = DictReader(f, delimiter=';')
@ -268,7 +270,7 @@ def importer_resultats_circo(engine: Engine, verbose: bool = False) -> None:
def importer_resultats_departement(engine: Engine, verbose: bool = False) -> None: def importer_resultats_departement(engine: Engine, verbose: bool = False) -> None:
file = get_file("https://www.data.gouv.fr/fr/datasets/r/b77cc4da-644f-4323-b6f7-ae6fe9b33f86", file = get_file("https://www.data.gouv.fr/fr/datasets/r/b77cc4da-644f-4323-b6f7-ae6fe9b33f86",
"resultats-europeennes-par-departement.csv") "resultats-europeennes-2024-par-departement.csv")
with file.open('r') as f: with file.open('r') as f:
reader = DictReader(f, delimiter=';') reader = DictReader(f, delimiter=';')
@ -330,7 +332,7 @@ def importer_resultats_departement(engine: Engine, verbose: bool = False) -> Non
def importer_resultats_region(engine: Engine, verbose: bool = False) -> None: def importer_resultats_region(engine: Engine, verbose: bool = False) -> None:
file = get_file("https://www.data.gouv.fr/fr/datasets/r/7c3a854b-7344-4c68-b1f9-9d651b4ca823", file = get_file("https://www.data.gouv.fr/fr/datasets/r/7c3a854b-7344-4c68-b1f9-9d651b4ca823",
"resultats-europeennes-par-region.csv") "resultats-europeennes-2024-par-region.csv")
with file.open('r') as f: with file.open('r') as f:
reader = DictReader(f, delimiter=';') reader = DictReader(f, delimiter=';')
@ -415,7 +417,11 @@ def calculer_resultats_france(engine: Engine, verbose: bool = False) -> None:
session.commit() session.commit()
def run(engine: Engine, verbose: bool = False) -> None: def run(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
if data_round != 0 and data_round != 1:
# Un seul tour à l'élection européenne
return
importer_resultats_region(engine, verbose) importer_resultats_region(engine, verbose)
importer_resultats_departement(engine, verbose) importer_resultats_departement(engine, verbose)
calculer_resultats_france(engine, verbose) calculer_resultats_france(engine, verbose)

View File

@ -0,0 +1 @@
from . import export_resultats, import_candidats, import_resultats

View File

@ -0,0 +1,494 @@
import json
from pathlib import Path
from sqlalchemy import Engine, select
from sqlalchemy.orm import Session
from tqdm import tqdm
from nupes.models.geographie import BureauVote
from nupes.models.legislatives2022 import *
DATA_DIR = Path(__file__).parent.parent.parent.parent / 'data'
def exporter_nuances(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
blocs = session.execute(select(BlocLegislatives2022)).scalars().all()
blocs_json = []
for bloc in blocs:
bloc_json = {'id': bloc.id, 'nom': bloc.nom, 'couleur': bloc.couleur}
blocs_json.append(bloc_json)
file = DATA_DIR / "resultats" / "legislatives" / "2022" / "blocs.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(blocs_json, f)
nuances = session.execute(select(NuanceLegislatives2022)).scalars().all()
nuances_json = []
for nuance in nuances:
nuance_json = {
'code': nuance.code,
'nom': nuance.nom,
'couleur': nuance.couleur,
"bloc": nuance.bloc.nom,
}
nuances_json.append(nuance_json)
file = DATA_DIR / "resultats" / "legislatives" / "2022" / "nuances.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(nuances_json, f)
def exporter_candidats(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
circonscriptions = session.execute(select(Circonscription)).scalars().all()
for circonscription in tqdm(circonscriptions, desc="Candidat⋅es", disable=not verbose):
candidats = session.execute(select(CandidatLegislatives2022)
.filter_by(circonscription_id=circonscription.id)).scalars().all()
candidats_json = []
for candidat in candidats:
candidat_json = {
'numero': candidat.numero,
'nuance': candidat.nuance_id,
'bloc': candidat.nuance.bloc.nom,
'nom': candidat.nom,
'prenom': candidat.prenom,
'nom_suppleance': candidat.nom_suppleance,
'prenom_suppleance': candidat.prenom_suppleance,
}
candidats_json.append(candidat_json)
file = DATA_DIR / "resultats" / "legislatives" / "2022" / "candidats" / f"{circonscription.id}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(candidats_json, f)
def exporter_resultats_france(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)).scalar_one_or_none()
if not resultats_france:
resultats_france = ResultatsFranceLegislatives2022()
session.add(resultats_france)
resultats_dict = {
'zone': {
'type': "france",
'regions': [reg.code_insee for reg in session.execute(select(Region)).scalars().all()],
'departements': [dpt.code_insee for dpt in session.execute(select(Departement)).scalars().all()],
'circonscriptions': [circo.id for circo in session.execute(select(Circonscription)).scalars().all()],
'geometry': {},
},
'tour1': {
'inscrits': resultats_france.inscrits_t1,
'votants': resultats_france.votants_t1,
'abstentions': resultats_france.abstentions_t1,
'exprimes': resultats_france.exprimes_t1,
'blancs': resultats_france.blancs_t1,
'nuls': resultats_france.nuls_t1,
},
'tour2': {
'inscrits': resultats_france.inscrits_t2,
'votants': resultats_france.votants_t2,
'abstentions': resultats_france.abstentions_t2,
'exprimes': resultats_france.exprimes_t2,
'blancs': resultats_france.blancs_t2,
'nuls': resultats_france.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_nuance in resultats_france.voix:
resultats_t1[voix_nuance.nuance_id] = voix_nuance.voix_t1
resultats_t2[voix_nuance.nuance_id] = voix_nuance.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2022" / "france.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
def exporter_resultats_regions(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
regions = session.execute(select(Region)).scalars().all()
regions_json = []
regions_iterator = tqdm(regions, desc="Régions") if verbose else regions
for region in regions_iterator:
region_json = {
'type': "region",
'code_insee': region.code_insee,
'nom': region.libelle,
'departements': [dpt.code_insee for dpt in region.departements],
'circonscriptions': [
circo.id for circo in session.execute(
select(Circonscription).join(Departement).filter_by(region_code=region.code_insee))
.scalars().all()
],
'geometry': region.geometry,
}
regions_json.append(region_json)
resultats_region = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=region.code_insee)).scalar_one_or_none()
if not resultats_region:
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)).scalar_one()
resultats_region = ResultatsRegionLegislatives2022(region_id=region.code_insee,
resultats_france_id=resultats_france.id)
session.add(resultats_region)
resultats_dict = {
'zone': region_json,
'tour1': {
'inscrits': resultats_region.inscrits_t1,
'votants': resultats_region.votants_t1,
'abstentions': resultats_region.abstentions_t1,
'exprimes': resultats_region.exprimes_t1,
'blancs': resultats_region.blancs_t1,
'nuls': resultats_region.nuls_t1,
},
'tour2': {
'inscrits': resultats_region.inscrits_t2,
'votants': resultats_region.votants_t2,
'abstentions': resultats_region.abstentions_t2,
'exprimes': resultats_region.exprimes_t2,
'blancs': resultats_region.blancs_t2,
'nuls': resultats_region.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_nuance in resultats_region.voix:
resultats_t1[voix_nuance.nuance_id] = voix_nuance.voix_t1
resultats_t2[voix_nuance.nuance_id] = voix_nuance.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2022" / "region" / f"{region.code_insee}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
regions_file = DATA_DIR / "resultats" / "legislatives" / "2022" / "region" / "regions.json"
if not regions_file.parent.is_dir():
regions_file.parent.mkdir(parents=True)
with regions_file.open('w') as f:
json.dump(regions_json, f)
def exporter_resultats_departements(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
departements = session.execute(select(Departement)).scalars().all()
departements_json = []
iterator = tqdm(departements, desc="Départements") if verbose else departements
for departement in iterator:
departement_json = {
'type': "departement",
'code_insee': departement.code_insee,
'nom': departement.libelle,
'region': departement.region_code,
'circonscriptions': [circo.id for circo in departement.circonscriptions],
'communes': [commune.code_insee for commune in departement.communes],
'geometry': departement.geometry,
}
departements_json.append(departement_json)
resultats_departement = session.execute(
select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=departement.code_insee)).scalar_one_or_none()
if not resultats_departement:
resultats_region = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=departement.region_code)).scalar_one()
resultats_departement = ResultatsDepartementLegislatives2022(dpt_id=departement.code_insee,
resultats_region_id=resultats_region.id)
session.add(resultats_departement)
resultats_dict = {
'zone': departement_json,
'tour1': {
'inscrits': resultats_departement.inscrits_t1,
'votants': resultats_departement.votants_t1,
'abstentions': resultats_departement.abstentions_t1,
'exprimes': resultats_departement.exprimes_t1,
'blancs': resultats_departement.blancs_t1,
'nuls': resultats_departement.nuls_t1,
},
'tour2': {
'inscrits': resultats_departement.inscrits_t2,
'votants': resultats_departement.votants_t2,
'abstentions': resultats_departement.abstentions_t2,
'exprimes': resultats_departement.exprimes_t2,
'blancs': resultats_departement.blancs_t2,
'nuls': resultats_departement.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_nuance in resultats_departement.voix:
resultats_t1[voix_nuance.nuance_id] = voix_nuance.voix_t1
resultats_t2[voix_nuance.nuance_id] = voix_nuance.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2022" / "departement" / f"{departement.code_insee}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
departements_file = DATA_DIR / "resultats" / "legislatives" / "2022" / "departement" / "departements.json"
if not departements_file.parent.is_dir():
departements_file.parent.mkdir(parents=True)
with departements_file.open('w') as f:
json.dump(departements_json, f)
def exporter_resultats_circonscriptions(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
circonscriptions = session.execute(select(Circonscription)).scalars().all()
circonscriptions_json = []
iterator = tqdm(circonscriptions, desc="Circonscriptions") if verbose else circonscriptions
for circonscription in iterator:
circonscription_json = {
'type': "circonscription",
'id': circonscription.id,
'departement': circonscription.departement_code,
'numero': circonscription.numero,
'bureaux_vote': [bv.id for bv in circonscription.bureaux_vote],
'geometry': circonscription.geometry,
}
circonscriptions_json.append(circonscription_json)
resultats_circonscription = session.execute(
select(ResultatsCirconscriptionLegislatives2022)
.filter_by(circo_id=circonscription.id)).scalar_one_or_none()
if not resultats_circonscription:
resultats_departement = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=circonscription.departement_code)) \
.scalar_one()
resultats_circonscription = ResultatsCirconscriptionLegislatives2022(
circo_id=circonscription.id, resultats_departement_id=resultats_departement.id)
session.add(resultats_circonscription)
resultats_dict = {
'zone': circonscription_json,
'tour1': {
'inscrits': resultats_circonscription.inscrits_t1,
'votants': resultats_circonscription.votants_t1,
'abstentions': resultats_circonscription.abstentions_t1,
'exprimes': resultats_circonscription.exprimes_t1,
'blancs': resultats_circonscription.blancs_t1,
'nuls': resultats_circonscription.nuls_t1,
},
'tour2': {
'inscrits': resultats_circonscription.inscrits_t2,
'votants': resultats_circonscription.votants_t2,
'abstentions': resultats_circonscription.abstentions_t2,
'exprimes': resultats_circonscription.exprimes_t2,
'blancs': resultats_circonscription.blancs_t2,
'nuls': resultats_circonscription.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_candidat in resultats_circonscription.voix:
resultats_t1[voix_candidat.candidat.numero] = voix_candidat.voix_t1
resultats_t2[voix_candidat.candidat.numero] = voix_candidat.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2022" / "circonscription" / f"{circonscription.id}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
circonscriptions_file = (DATA_DIR / "resultats" / "legislatives" / "2022"
/ "circonscription" / "circonscriptions.json")
if not circonscriptions_file.parent.is_dir():
circonscriptions_file.parent.mkdir(parents=True)
with circonscriptions_file.open('w') as f:
json.dump(circonscriptions_json, f)
def exporter_resultats_communes(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
communes = session.execute(select(Commune)).scalars().all()
communes_json = []
iterator = tqdm(communes, desc="Communes") if verbose else communes
for commune in iterator:
commune_json = {
'type': "commune",
'code_insee': commune.code_insee,
'nom': commune.libelle,
'departement': commune.departement_code,
'bureaux_vote': [bv.id for bv in commune.bureaux_vote],
'geometry': commune.geometry,
}
communes_json.append(commune_json)
resultats_commune = session.execute(
select(ResultatsCommuneLegislatives2022).filter_by(commune_id=commune.code_insee)).scalar_one_or_none()
if not resultats_commune:
resultats_departement = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=commune.departement_code)).scalar_one()
resultats_commune = ResultatsCommuneLegislatives2022(commune_id=commune.code_insee,
resultats_dpt_id=resultats_departement.id)
session.add(resultats_commune)
resultats_dict = {
'zone': commune_json,
'tour1': {
'inscrits': resultats_commune.inscrits_t1,
'votants': resultats_commune.votants_t1,
'abstentions': resultats_commune.abstentions_t1,
'exprimes': resultats_commune.exprimes_t1,
'blancs': resultats_commune.blancs_t1,
'nuls': resultats_commune.nuls_t1,
},
'tour2': {
'inscrits': resultats_commune.inscrits_t2,
'votants': resultats_commune.votants_t2,
'abstentions': resultats_commune.abstentions_t2,
'exprimes': resultats_commune.exprimes_t2,
'blancs': resultats_commune.blancs_t2,
'nuls': resultats_commune.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_nuance in resultats_commune.voix:
resultats_t1[voix_nuance.nuance_id] = voix_nuance.voix_t1
resultats_t2[voix_nuance.nuance_id] = voix_nuance.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2022" / "commune" / f"{commune.code_insee}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
communes_file = DATA_DIR / "resultats" / "legislatives" / "2022" / "commune" / "communes.json"
if not communes_file.parent.is_dir():
communes_file.parent.mkdir(parents=True)
with communes_file.open('w') as f:
json.dump(communes_json, f)
def exporter_resultats_bureaux_vote(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
bureaux_vote = session.execute(select(BureauVote)).scalars().all()
bureaux_vote_json = []
iterator = tqdm(bureaux_vote, desc="Bureaux de vote") if verbose else bureaux_vote
for bureau_vote in iterator:
bureau_vote_json = {
'type': "bureau_vote",
'id': bureau_vote.id,
'libelle': bureau_vote.libelle,
'commune': bureau_vote.commune_code,
'circonscription': bureau_vote.circo_code,
'geometry': bureau_vote.geometry,
}
bureaux_vote_json.append(bureau_vote_json)
resultats_bureau_vote = session.execute(
select(ResultatsBureauVoteLegislatives2022).filter_by(bv_id=bureau_vote.id)).scalar_one_or_none()
if not resultats_bureau_vote:
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2022)
.filter_by(commune_id=bureau_vote.commune_code)).scalar_one()
resultats_bureau_vote = ResultatsBureauVoteLegislatives2022(bv_id=bureau_vote.id,
resultats_commune_id=resultats_commune.id)
session.add(resultats_bureau_vote)
resultats_dict = {
'zone': bureau_vote_json,
'tour1': {
'inscrits': resultats_bureau_vote.inscrits_t1,
'votants': resultats_bureau_vote.votants_t1,
'abstentions': resultats_bureau_vote.abstentions_t1,
'exprimes': resultats_bureau_vote.exprimes_t1,
'blancs': resultats_bureau_vote.blancs_t1,
'nuls': resultats_bureau_vote.nuls_t1,
},
'tour2': {
'inscrits': resultats_bureau_vote.inscrits_t2,
'votants': resultats_bureau_vote.votants_t2,
'abstentions': resultats_bureau_vote.abstentions_t2,
'exprimes': resultats_bureau_vote.exprimes_t2,
'blancs': resultats_bureau_vote.blancs_t2,
'nuls': resultats_bureau_vote.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_candidat in resultats_bureau_vote.voix:
resultats_t1[voix_candidat.candidat.numero] = voix_candidat.voix_t1
resultats_t2[voix_candidat.candidat.numero] = voix_candidat.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2022" / "bureau_vote" / f"{bureau_vote.id}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
bureaux_vote_file = DATA_DIR / "resultats" / "legislatives" / "2022" / "bureau_vote" / "bureaux_vote.json"
if not bureaux_vote_file.parent.is_dir():
bureaux_vote_file.parent.mkdir(parents=True)
with bureaux_vote_file.open('w') as f:
json.dump(bureaux_vote_json, f)
def run(engine: Engine, verbose: bool = False) -> None:
exporter_nuances(engine, verbose)
exporter_candidats(engine, verbose)
exporter_resultats_france(engine, verbose)
exporter_resultats_regions(engine, verbose)
exporter_resultats_departements(engine, verbose)
exporter_resultats_circonscriptions(engine, verbose)
exporter_resultats_communes(engine, verbose)
exporter_resultats_bureaux_vote(engine, verbose)

View File

@ -0,0 +1,151 @@
import csv
import datetime
from sqlalchemy import Engine, select
from sqlalchemy.orm import Session
from tqdm import tqdm
from nupes.cache import get_file
from nupes.models import Genre
from nupes.models.legislatives2022 import BlocLegislatives2022, NuanceLegislatives2022, CandidatLegislatives2022
def creer_blocs(engine: Engine, verbose: bool = False) -> None:
blocs = [
{"id": 1, "nom": "Gauche", "couleur": "#BB1840"},
{"id": 2, "nom": "Droite libérale", "couleur": "#FFEB00"},
{"id": 3, "nom": "Droite conservatrice", "couleur": "#0066CC"},
{"id": 4, "nom": "Extrême droite", "couleur": "#404040"},
{"id": 5, "nom": "Autres", "couleur": "#DCBFA3"}
]
with Session(engine) as session:
for bloc_dict in blocs:
if bloc := session.execute(select(BlocLegislatives2022).filter_by(id=bloc_dict["id"])).scalar_one_or_none():
bloc.nom = bloc_dict["nom"]
bloc.couleur = bloc_dict["couleur"]
else:
session.add(BlocLegislatives2022(**bloc_dict))
session.commit()
def creer_nuances(engine: Engine, verbose: bool = False) -> None:
nuances = [
{"code": "DXG", "nom": "Divers extrême gauche", "couleur": "#BB0000", "bloc_id": 1},
{"code": "RDG", "nom": "Parti radical de gauche", "couleur": "#FFD1DC", "bloc_id": 1},
{"code": "NUP", "nom": "Nouvelle union populaire écologique et sociale", "couleur": "#E4032E", "bloc_id": 1},
{"code": "DVG", "nom": "Divers gauche", "couleur": "#FFC0C0", "bloc_id": 1},
{"code": "ECO", "nom": "Écologistes", "couleur": "#77FF77", "bloc_id": 5},
{"code": "DIV", "nom": "Divers", "couleur": "#DCDCDC", "bloc_id": 5},
{"code": "REG", "nom": "Régionalistes", "couleur": "#DCBFA3", "bloc_id": 5},
{"code": "ENS", "nom": "Ensemble ! (Majorité présidentielle)", "couleur": "#FFEB00", "bloc_id": 2},
{"code": "DVC", "nom": "Divers centre", "couleur": "#FAC577", "bloc_id": 2},
{"code": "UDI", "nom": "Union des Démocrates et Indépendants", "couleur": "#00FFFF", "bloc_id": 3},
{"code": "LR", "nom": "Les Républicains", "couleur": "#0066CC", "bloc_id": 3},
{"code": "DVD", "nom": "Divers droite", "couleur": "#26C4EC", "bloc_id": 3},
{"code": "DSV", "nom": "Droite souverainiste", "couleur": "#8040C0", "bloc_id": 4},
{"code": "REC", "nom": "Reconquête !", "couleur": "#404040", "bloc_id": 4},
{"code": "RN", "nom": "Rassemblement national", "couleur": "#0D378A", "bloc_id": 4},
{"code": "DXD", "nom": "Divers extrême droite", "couleur": "#404040", "bloc_id": 4},
]
with Session(engine) as session:
for nuance_dict in nuances:
if nuance := session.execute(select(NuanceLegislatives2022)
.filter_by(code=nuance_dict["code"])).scalar_one_or_none():
nuance.nom = nuance_dict["nom"]
nuance.couleur = nuance_dict["couleur"]
nuance.bloc_id = nuance_dict["bloc_id"]
else:
session.add(NuanceLegislatives2022(**nuance_dict))
session.commit()
def importer_candidats(engine: Engine, verbose: bool = False) -> None:
DATASET_URL = "https://www.data.gouv.fr/fr/datasets/r/c79af2f3-1733-4df3-be37-caebacbc1321"
file = get_file(DATASET_URL, "candidats_legislatives_2022.tsv")
with file.open('r', encoding="ISO-8859-1") as f:
with Session(engine) as session:
reader = csv.DictReader(f, delimiter='\t')
for line in tqdm(reader, desc="Candidat⋅es", disable=not verbose):
line: dict[str, str]
numero_panneau = int(line.get("N° panneau"))
code_dpt = line.get("Code du département")
match code_dpt:
case "ZA":
code_dpt = "971"
case "ZB":
code_dpt = "972"
case "ZC":
code_dpt = "973"
case "ZD":
code_dpt = "974"
case "ZS":
code_dpt = "975"
case "ZM":
code_dpt = "976"
case "ZX":
code_dpt = "977"
case "ZW":
code_dpt = "986"
case "ZP":
code_dpt = "987"
case "ZN":
code_dpt = "988"
code_circo = line.get("Code circonscription")
circo_id = f"{code_dpt}-{code_circo}"
nuance_id = line.get("Nuance candidat")
nuance = session.execute(select(NuanceLegislatives2022).filter_by(code=nuance_id)).scalar_one()
if candidat := session.execute(select(CandidatLegislatives2022)
.filter_by(circonscription_id=circo_id, numero=numero_panneau)) \
.scalar_one_or_none():
candidat.nuance_id = line['Nuance candidat']
candidat.bloc_id = nuance.bloc_id
candidat.nom = line['Nom candidat']
candidat.prenom = line['Prénom candidat']
candidat.sexe = CandidatLegislatives2022.Genre(line['Sexe candidat'])
candidat.date_naissance = datetime.datetime.strptime(line['Date naissance candidat'],
"%d/%m/%Y").date()
candidat.profession = line['Profession candidat']
candidat.sortant = line['Le candidat est sortant'] == "Oui"
candidat.nom_suppleance = line['Nom remplaçant']
candidat.prenom_suppleance = line['Prénom remplaçant']
candidat.sexe_suppleance = CandidatLegislatives2022.Genre(line['Sexe remplaçant'])
candidat.date_naissance_suppleance = datetime.datetime.strptime(line['Date naiss. remplaçant'],
"%d/%m/%Y").date()
candidat.sortant = line['Le remplaçant est sortant'] == "Oui"
else:
candidat = CandidatLegislatives2022(
circonscription_id=circo_id,
numero=numero_panneau,
nuance_id=nuance_id,
bloc_id=nuance.bloc_id,
nom=line['Nom candidat'],
prenom=line['Prénom candidat'],
sexe=Genre(line['Sexe candidat']).name,
date_naissance=datetime.datetime.strptime(line['Date naissance candidat'], "%d/%m/%Y").date(),
profession=line['Profession candidat'],
sortant=line['Le candidat est sortant'] == "Oui",
nom_suppleance=line['Nom remplaçant'],
prenom_suppleance=line['Prénom remplaçant'],
sexe_suppleance=Genre(line['Sexe remplaçant']).name,
date_naissance_suppleance=datetime.datetime.strptime(line['Date naiss. remplaçant'],
"%d/%m/%Y").date(),
sortant_suppleance=line['Le remplaçant est sortant'] == "Oui",
)
session.add(candidat)
session.commit()
def run(engine: Engine, verbose: bool = False) -> None:
creer_blocs(engine, verbose)
creer_nuances(engine, verbose)
importer_candidats(engine, verbose)

View File

@ -0,0 +1,696 @@
import csv
from sqlalchemy import Engine, select
from sqlalchemy.orm import Session
from tqdm import tqdm
from nupes.cache import get_file
from nupes.models import BureauVote
from nupes.models.legislatives2022 import *
def importer_resultats_bv(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/a1f73b85-8194-44f4-a2b7-c343edb47d32"),
(2, "https://www.data.gouv.fr/fr/datasets/r/96ffddda-59b4-41b8-a6a3-dfe1adb7fa36")]
with Session(engine) as session:
candidats = {(candidat.circonscription_id, candidat.numero): candidat
for candidat in session.execute(select(CandidatLegislatives2022)).scalars().all()}
bv_ids = {(bv.commune_code, bv.code_bureau): bv.id
for bv in session.execute(select(BureauVote)).scalars().all()}
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2022-t{tour}-par-bureau-de-vote.csv")
with file.open('r', encoding="ISO-8859-1") as f:
reader = csv.reader(f, delimiter=';')
next(reader)
with Session(engine) as session:
for row in tqdm(reader, desc=f"Bureau de vote tour {tour}", disable=not verbose):
dpt_code = row[0]
match dpt_code:
case "ZA":
dpt_code = "971"
case "ZB":
dpt_code = "972"
case "ZC":
dpt_code = "973"
case "ZD":
dpt_code = "974"
case "ZS":
dpt_code = "975"
case "ZM":
dpt_code = "976"
case "ZX":
dpt_code = "977"
case "ZW":
dpt_code = "986"
case "ZP":
dpt_code = "987"
case "ZN":
dpt_code = "988"
if dpt_code == "987" or dpt_code == "988":
# Les communes de Polynésie française ne sont pas importées
continue
com_code = str(dpt_code + row[4][(1 if len(dpt_code) == 3 else 0):]).zfill(5)
if com_code == "98601":
# 3 royaumes à Wallis-et-Futuna, mais un seul résultat de commune
com_code = "98611"
if com_code.startswith("987"): # Les communes de Polynésie française ne sont pas importées
continue
bv_code = row[6]
if (com_code, bv_code) not in bv_ids:
print(f"Bureau de vote {com_code}_{bv_code} non trouvé")
continue
bv_id = bv_ids[(com_code, bv_code)]
circo_code = row[2]
circo_id = f"{dpt_code.zfill(2)}-{circo_code.zfill(2)}"
resultats_bv = session.execute(select(ResultatsBureauVoteLegislatives2022)
.filter_by(bv_id=bv_id)).scalar_one_or_none()
if not resultats_bv:
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2022)
.filter_by(commune_id=com_code)).scalar_one_or_none()
if not resultats_commune:
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=dpt_code)) \
.scalar_one_or_none()
if not resultats_dpt:
dpt = session.execute(select(Departement).filter_by(code_insee=dpt_code)) \
.scalar_one()
resultats_reg = session.execute(
select(ResultatsRegionLegislatives2022).filter_by(region_id=dpt.region_code)) \
.scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)) \
.scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2022())
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)) \
.scalar_one()
resultats_reg = ResultatsRegionLegislatives2022(
region_id=str(dpt.region_code), resultats_france_id=resultats_france.id)
session.add(resultats_reg)
resultats_reg = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=dpt.region_code)).scalar_one()
resultats_dpt = ResultatsDepartementLegislatives2022(
dpt_id=dpt_code, resultats_region_id=resultats_reg.id)
session.add(resultats_dpt)
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=dpt_code)).scalar_one()
resultats_commune = ResultatsCommuneLegislatives2022(commune_id=com_code,
resultats_dpt_id=resultats_dpt.id)
session.add(resultats_commune)
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2022)
.filter_by(commune_id=com_code)).scalar_one()
resultats_circo = session.execute(select(ResultatsCirconscriptionLegislatives2022)
.filter_by(circo_id=circo_id)).scalar_one_or_none()
resultats_bv = ResultatsBureauVoteLegislatives2022(bv_id=bv_id,
resultats_commune_id=resultats_commune.id,
resultats_circo_id=resultats_circo.id)
session.add(resultats_bv)
resultats_bv = session.execute(select(ResultatsBureauVoteLegislatives2022)
.filter_by(bv_id=bv_id)).scalar_one()
if tour == 1:
resultats_bv.inscrits_t1 = int(row[7])
resultats_bv.votants_t1 = int(row[10])
resultats_bv.abstentions_t1 = int(row[8])
resultats_bv.exprimes_t1 = int(row[18])
resultats_bv.blancs_t1 = int(row[12])
resultats_bv.nuls_t1 = int(row[15])
elif tour == 2:
resultats_bv.inscrits_t2 = int(row[7])
resultats_bv.votants_t2 = int(row[10])
resultats_bv.abstentions_t2 = int(row[8])
resultats_bv.exprimes_t2 = int(row[18])
resultats_bv.blancs_t2 = int(row[12])
resultats_bv.nuls_t2 = int(row[15])
row_voix = row[21:]
for i in range(len(row_voix) // 8):
bloc_voix = row_voix[i * 8:(i + 1) * 8]
numero = bloc_voix[0]
voix = int(bloc_voix[5])
candidat = candidats[(circo_id, int(numero))]
voix_candidat_bv = session.execute(select(VoixBureauVoteLegislatives2022)
.filter_by(resultats_bureau_vote_id=resultats_bv.id,
candidat_id=candidat.id)) \
.scalar_one_or_none()
if not voix_candidat_bv:
voix_candidat_bv = VoixBureauVoteLegislatives2022(
resultats_bureau_vote_id=resultats_bv.id, candidat_id=candidat.id)
session.add(voix_candidat_bv)
if tour == 1:
voix_candidat_bv.voix_t1 = voix
elif tour == 2:
voix_candidat_bv.voix_t2 = voix
session.commit()
def importer_resultats_commune(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/a9a82bcc-304e-491f-a4f0-c06575113745"),
(2, "https://www.data.gouv.fr/fr/datasets/r/e79b2e51-0841-4266-b626-57cb271c7a35")]
with Session(engine) as session:
for resultats_commune in session.execute(select(ResultatsCommuneLegislatives2022)).scalars().all():
if data_round == 0 or data_round == 1:
resultats_commune.inscrits_t1 = 0
resultats_commune.votants_t1 = 0
resultats_commune.abstentions_t1 = 0
resultats_commune.exprimes_t1 = 0
resultats_commune.blancs_t1 = 0
resultats_commune.nuls_t1 = 0
if data_round == 0 or data_round == 2:
resultats_commune.inscrits_t2 = 0
resultats_commune.votants_t2 = 0
resultats_commune.abstentions_t2 = 0
resultats_commune.exprimes_t2 = 0
resultats_commune.blancs_t2 = 0
resultats_commune.nuls_t2 = 0
for voix_nuance in resultats_commune.voix:
if data_round == 0 or data_round == 1:
voix_nuance.voix_t1 = 0
if data_round == 0 or data_round == 2:
voix_nuance.voix_t2 = 0
session.commit()
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url,
f"resultats-legislatives-2022-t{tour}-par-commune.csv")
with file.open('r', encoding="ISO-8859-1") as f:
reader = csv.reader(f, delimiter=';')
next(reader)
with Session(engine) as session:
for row in tqdm(reader, desc=f"Commune tour {tour}", disable=not verbose):
dpt_code = row[0]
match dpt_code:
case "ZA":
dpt_code = "971"
case "ZB":
dpt_code = "972"
case "ZC":
dpt_code = "973"
case "ZD":
dpt_code = "974"
case "ZS":
dpt_code = "975"
case "ZM":
dpt_code = "976"
case "ZX":
dpt_code = "977"
case "ZW":
dpt_code = "986"
case "ZP":
dpt_code = "987"
case "ZN":
dpt_code = "988"
if dpt_code == "987" or dpt_code == "988":
# Les communes de Polynésie française ne sont pas importées
continue
com_code = str(dpt_code + row[4][(1 if len(dpt_code) == 3 else 0):]).zfill(5)
if com_code == "98601":
# 3 royaumes à Wallis-et-Futuna, mais un seul résultat de commune
com_code = "98611"
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2022)
.filter_by(commune_id=com_code)).scalar_one_or_none()
if not resultats_commune:
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=dpt_code)).scalar_one_or_none()
if not resultats_dpt:
dpt = session.execute(select(Departement)
.filter_by(code_insee=f"{dpt_code.zfill(2)}")).scalar_one()
resultats_reg = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=dpt.region_code)).scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)) \
.scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2022())
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)) \
.scalar_one()
resultats_reg = ResultatsRegionLegislatives2022(region_id=str(dpt.region_code),
resultats_france_id=resultats_france.id)
session.add(resultats_reg)
resultats_reg = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=dpt.region_code)).scalar_one()
resultats_dpt = ResultatsDepartementLegislatives2022(dpt_id=dpt_code,
resultats_region_id=resultats_reg.id)
session.add(resultats_dpt)
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=dpt_code)).scalar_one()
resultats_commune = ResultatsCommuneLegislatives2022(commune_id=com_code,
resultats_dpt_id=resultats_dpt.id)
session.add(resultats_commune)
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2022)
.filter_by(commune_id=com_code)).scalar_one()
if tour == 1:
resultats_commune.inscrits_t1 = int(row[7])
resultats_commune.votants_t1 = int(row[10])
resultats_commune.abstentions_t1 = int(row[8])
resultats_commune.exprimes_t1 = int(row[18])
resultats_commune.blancs_t1 = int(row[12])
resultats_commune.nuls_t1 = int(row[15])
elif tour == 2:
resultats_commune.inscrits_t2 = int(row[7])
resultats_commune.votants_t2 = int(row[10])
resultats_commune.abstentions_t2 = int(row[8])
resultats_commune.exprimes_t2 = int(row[18])
resultats_commune.blancs_t2 = int(row[12])
resultats_commune.nuls_t2 = int(row[15])
row_voix = row[21:]
for i in range(len(row_voix) // 8):
bloc_voix = row_voix[i * 8:(i + 1) * 8]
nuance_code = bloc_voix[4]
voix = int(bloc_voix[5])
voix_nuance_commune = session.execute(select(VoixCommuneLegislatives2022)
.filter_by(resultats_commune_id=resultats_commune.id,
nuance_id=nuance_code)) \
.scalar_one_or_none()
if not voix_nuance_commune:
voix_nuance_commune = VoixCommuneLegislatives2022(resultats_commune_id=resultats_commune.id,
nuance_id=nuance_code,
voix_t1=0, voix_t2=0)
session.add(voix_nuance_commune)
if tour == 1:
voix_nuance_commune.voix_t1 += voix
elif tour == 2:
voix_nuance_commune.voix_t2 += voix
session.commit()
def importer_resultats_circo(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/114b13e8-7ff9-437f-9ec8-7a29258a80e3"),
(2, "https://www.data.gouv.fr/fr/datasets/r/436b9eaa-64e1-46bd-ad1d-9638ebbd6caf")]
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2022-t{tour}-par-circonscription.csv")
with file.open('r', encoding="ISO-8859-1") as f:
reader = csv.reader(f, delimiter=';')
next(reader)
with Session(engine) as session:
for row in tqdm(reader, desc=f"Circonscription tour {tour}", disable=not verbose):
dpt_code = row[0]
circo_code = row[2]
match dpt_code:
case "ZA":
dpt_code = "971"
case "ZB":
dpt_code = "972"
case "ZC":
dpt_code = "973"
case "ZD":
dpt_code = "974"
case "ZS":
dpt_code = "975"
case "ZM":
dpt_code = "976"
case "ZX":
dpt_code = "977"
case "ZW":
dpt_code = "986"
case "ZP":
dpt_code = "987"
case "ZN":
dpt_code = "988"
circo_id = f"{dpt_code.zfill(2)}-{circo_code.zfill(2)}"
resultats_circo = session.execute(select(ResultatsCirconscriptionLegislatives2022)
.filter_by(circo_id=circo_id)).scalar_one_or_none()
if not resultats_circo:
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=dpt_code)).scalar_one_or_none()
if not resultats_dpt:
dpt = session.execute(select(Departement).filter_by(code_insee=f"{dpt_code.zfill(2)}")) \
.scalar_one()
resultats_reg = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=dpt.region_code)) \
.scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)) \
.scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2022())
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)).scalar_one()
resultats_reg = ResultatsRegionLegislatives2022(region_id=str(dpt.region_code),
resultats_france_id=resultats_france.id)
session.add(resultats_reg)
resultats_reg = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=dpt.region_code)).scalar_one()
resultats_dpt = ResultatsDepartementLegislatives2022(dpt_id=dpt_code,
resultats_region_id=resultats_reg.id)
session.add(resultats_dpt)
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=dpt_code)).scalar_one()
resultats_circo = ResultatsCirconscriptionLegislatives2022(
circo_id=circo_id, resultats_departement_id=resultats_dpt.id)
session.add(resultats_circo)
resultats_circo = session.execute(select(ResultatsCirconscriptionLegislatives2022)
.filter_by(circo_id=circo_id)).scalar_one()
if tour == 1:
resultats_circo.inscrits_t1 = int(row[5])
resultats_circo.votants_t1 = int(row[8])
resultats_circo.abstentions_t1 = int(row[6])
resultats_circo.exprimes_t1 = int(row[16])
resultats_circo.blancs_t1 = int(row[10])
resultats_circo.nuls_t1 = int(row[13])
elif tour == 2:
resultats_circo.inscrits_t2 = int(row[5])
resultats_circo.votants_t2 = int(row[8])
resultats_circo.abstentions_t2 = int(row[6])
resultats_circo.exprimes_t2 = int(row[16])
resultats_circo.blancs_t2 = int(row[10])
resultats_circo.nuls_t2 = int(row[13])
row_voix = row[19:]
for i in range(len(row_voix) // 9):
bloc_voix = row_voix[i * 9:(i + 1) * 9]
numero = bloc_voix[0]
voix = int(bloc_voix[5])
candidat = session.execute(select(CandidatLegislatives2022)
.filter_by(circonscription_id=circo_id, numero=numero)) \
.scalar_one_or_none()
voix_candidat_circo = session.execute(select(VoixCirconscriptionLegislatives2022)
.filter_by(resultats_circonscription_id=resultats_circo.id,
candidat_id=candidat.id)) \
.scalar_one_or_none()
if not voix_candidat_circo:
voix_candidat_circo = VoixCirconscriptionLegislatives2022(
resultats_circonscription_id=resultats_circo.id, candidat_id=candidat.id)
session.add(voix_candidat_circo)
if tour == 1:
voix_candidat_circo.voix_t1 = voix
elif tour == 2:
voix_candidat_circo.voix_t2 = voix
session.commit()
def importer_resultats_departement(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/4acba699-e512-4dc5-87c7-ba74db773633"),
(2, "https://www.data.gouv.fr/fr/datasets/r/bc76bd72-cf65-45b2-b651-7716dc3c5520")]
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2022-t{tour}-par-departement.csv")
with file.open('r', encoding="ISO-8859-1") as f:
reader = csv.reader(f, delimiter=';')
next(reader)
with Session(engine) as session:
for row in tqdm(reader, desc=f"Département tour {tour}", disable=not verbose):
dpt_code = row[0]
match dpt_code:
case "ZA":
dpt_code = "971"
case "ZB":
dpt_code = "972"
case "ZC":
dpt_code = "973"
case "ZD":
dpt_code = "974"
case "ZS":
dpt_code = "975"
case "ZM":
dpt_code = "976"
case "ZX":
dpt_code = "977"
case "ZW":
dpt_code = "986"
case "ZP":
dpt_code = "987"
case "ZN":
dpt_code = "988"
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=dpt_code)).scalar_one_or_none()
if not resultats_dpt:
dpt = session.execute(select(Departement)
.filter_by(code_insee=f"{dpt_code.zfill(2)}")) \
.scalar_one()
resultats_reg = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=dpt.region_code)) \
.scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)) \
.scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2022())
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)).scalar_one()
resultats_reg = ResultatsRegionLegislatives2022(region_id=str(dpt.region_code),
resultats_france_id=resultats_france.id)
session.add(resultats_reg)
resultats_reg = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=dpt.region_code)).scalar_one()
resultats_dpt = ResultatsDepartementLegislatives2022(dpt_id=dpt_code,
resultats_region_id=resultats_reg.id)
session.add(resultats_dpt)
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2022)
.filter_by(dpt_id=dpt_code)).scalar_one()
if tour == 1:
resultats_dpt.inscrits_t1 = int(row[3])
resultats_dpt.votants_t1 = int(row[6])
resultats_dpt.abstentions_t1 = int(row[4])
resultats_dpt.exprimes_t1 = int(row[14])
resultats_dpt.blancs_t1 = int(row[8])
resultats_dpt.nuls_t1 = int(row[11])
elif tour == 2:
resultats_dpt.inscrits_t2 = int(row[3])
resultats_dpt.votants_t2 = int(row[6])
resultats_dpt.abstentions_t2 = int(row[4])
resultats_dpt.exprimes_t2 = int(row[14])
resultats_dpt.blancs_t2 = int(row[8])
resultats_dpt.nuls_t2 = int(row[11])
row_voix = row[17:]
for i in range(len(row_voix) // 5):
bloc_voix = row_voix[i * 5:(i + 1) * 5]
nuance_code = bloc_voix[0]
voix = int(bloc_voix[1])
voix_nuance_dpt = session.execute(select(VoixDepartementLegislatives2022)
.filter_by(resultats_departement_id=resultats_dpt.id,
nuance_id=nuance_code)) \
.scalar_one_or_none()
if not voix_nuance_dpt:
voix_nuance_dpt = VoixDepartementLegislatives2022(resultats_departement_id=resultats_dpt.id,
nuance_id=nuance_code)
session.add(voix_nuance_dpt)
if tour == 1:
voix_nuance_dpt.voix_t1 = voix
elif tour == 2:
voix_nuance_dpt.voix_t2 = voix
session.commit()
def importer_resultats_region(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/f79576c9-9ddc-43f9-8d99-f0856550054e"),
(2, "https://www.data.gouv.fr/fr/datasets/r/fdba421a-d4e9-4f38-9753-982a7c065911")]
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2022-t{tour}-par-region.csv")
with file.open('r', encoding="ISO-8859-1") as f:
reader = csv.reader(f, delimiter=';')
next(reader)
with Session(engine) as session:
for row in tqdm(reader, desc=f"Région tour {tour}", disable=not verbose):
reg_code = row[0]
resultats_reg = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=reg_code)).scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)).scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2022())
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)).scalar_one()
resultats_reg = ResultatsRegionLegislatives2022(region_id=reg_code,
resultats_france_id=resultats_france.id)
session.add(resultats_reg)
session.commit()
resultats_reg = session.execute(select(ResultatsRegionLegislatives2022)
.filter_by(region_id=reg_code)).scalar_one()
if tour == 1:
resultats_reg.inscrits_t1 = int(row[3])
resultats_reg.votants_t1 = int(row[6])
resultats_reg.abstentions_t1 = int(row[4])
resultats_reg.exprimes_t1 = int(row[14])
resultats_reg.blancs_t1 = int(row[8])
resultats_reg.nuls_t1 = int(row[11])
elif tour == 2:
resultats_reg.inscrits_t2 = int(row[3])
resultats_reg.votants_t2 = int(row[6])
resultats_reg.abstentions_t2 = int(row[4])
resultats_reg.exprimes_t2 = int(row[14])
resultats_reg.blancs_t2 = int(row[8])
resultats_reg.nuls_t2 = int(row[11])
row_voix = row[17:]
for i in range(len(row_voix) // 5):
bloc_voix = row_voix[i * 5:(i + 1) * 5]
nuance_code = bloc_voix[0]
voix = int(bloc_voix[1])
voix_nuance_reg = session.execute(select(VoixRegionLegislatives2022)
.filter_by(resultats_region_id=resultats_reg.id,
nuance_id=nuance_code)) \
.scalar_one_or_none()
if not voix_nuance_reg:
voix_nuance_reg = VoixRegionLegislatives2022(resultats_region_id=resultats_reg.id,
nuance_id=nuance_code)
session.add(voix_nuance_reg)
if tour == 1:
voix_nuance_reg.voix_t1 = voix
elif tour == 2:
voix_nuance_reg.voix_t2 = voix
session.commit()
def importer_resultats_france(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/cbe72f2c-2c56-4251-89cb-213de8bfbea0"),
(2, "https://www.data.gouv.fr/fr/datasets/r/6639bb39-13ec-49dd-ab4d-1f8227b86c01")]
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2022-t{tour}-france-entiere.csv")
with file.open('r', encoding="ISO-8859-1") as f:
reader = csv.reader(f, delimiter=';')
next(reader)
with Session(engine) as session:
for row in tqdm(reader, desc=f"France Entière tour {tour}", disable=not verbose):
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)).scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2022())
session.commit()
resultats_france = session.execute(select(ResultatsFranceLegislatives2022)).scalar_one()
if tour == 1:
resultats_france.inscrits_t1 = int(row[3])
resultats_france.votants_t1 = int(row[6])
resultats_france.abstentions_t1 = int(row[4])
resultats_france.exprimes_t1 = int(row[14])
resultats_france.blancs_t1 = int(row[8])
resultats_france.nuls_t1 = int(row[11])
elif tour == 2:
resultats_france.inscrits_t2 = int(row[3])
resultats_france.votants_t2 = int(row[6])
resultats_france.abstentions_t2 = int(row[4])
resultats_france.exprimes_t2 = int(row[14])
resultats_france.blancs_t2 = int(row[8])
resultats_france.nuls_t2 = int(row[11])
row_voix = row[17:]
for i in range(len(row_voix) // 5):
bloc_voix = row_voix[i * 5:(i + 1) * 5]
nuance_code = bloc_voix[0]
voix = int(bloc_voix[1])
voix_nuance_france = session.execute(select(VoixFranceLegislatives2022)
.filter_by(resultats_france_id=resultats_france.id,
nuance_id=nuance_code)) \
.scalar_one_or_none()
if not voix_nuance_france:
voix_nuance_france = VoixFranceLegislatives2022(resultats_france_id=resultats_france.id,
nuance_id=nuance_code)
session.add(voix_nuance_france)
if tour == 1:
voix_nuance_france.voix_t1 = voix
elif tour == 2:
voix_nuance_france.voix_t2 = voix
session.commit()
def run(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
importer_resultats_france(engine, data_round, verbose)
importer_resultats_region(engine, data_round, verbose)
importer_resultats_departement(engine, data_round, verbose)
importer_resultats_circo(engine, data_round, verbose)
importer_resultats_commune(engine, data_round, verbose)
importer_resultats_bv(engine, data_round, verbose)

View File

@ -0,0 +1 @@
from . import export_resultats, import_candidats, import_resultats

View File

@ -0,0 +1,494 @@
import json
from pathlib import Path
from sqlalchemy import Engine, select
from sqlalchemy.orm import Session
from tqdm import tqdm
from nupes.models.geographie import BureauVote
from nupes.models.legislatives2024 import *
DATA_DIR = Path(__file__).parent.parent.parent.parent / 'data'
def exporter_nuances(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
blocs = session.execute(select(BlocLegislatives2024)).scalars().all()
blocs_json = []
for bloc in blocs:
bloc_json = {'id': bloc.id, 'nom': bloc.nom, 'couleur': bloc.couleur}
blocs_json.append(bloc_json)
file = DATA_DIR / "resultats" / "legislatives" / "2024" / "blocs.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(blocs_json, f)
nuances = session.execute(select(NuanceLegislatives2024)).scalars().all()
nuances_json = []
for nuance in nuances:
nuance_json = {
'code': nuance.code,
'nom': nuance.nom,
'couleur': nuance.couleur,
"bloc": nuance.bloc.nom,
}
nuances_json.append(nuance_json)
file = DATA_DIR / "resultats" / "legislatives" / "2024" / "nuances.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(nuances_json, f)
def exporter_candidats(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
circonscriptions = session.execute(select(Circonscription)).scalars().all()
for circonscription in tqdm(circonscriptions, desc="Candidat⋅es", disable=not verbose):
candidats = session.execute(select(CandidatLegislatives2024)
.filter_by(circonscription_id=circonscription.id)).scalars().all()
candidats_json = []
for candidat in candidats:
candidat_json = {
'numero': candidat.numero,
'nuance': candidat.nuance_id,
'bloc': candidat.nuance.bloc.nom,
'nom': candidat.nom,
'prenom': candidat.prenom,
'nom_suppleance': candidat.nom_suppleance,
'prenom_suppleance': candidat.prenom_suppleance,
}
candidats_json.append(candidat_json)
file = DATA_DIR / "resultats" / "legislatives" / "2024" / "candidats" / f"{circonscription.id}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(candidats_json, f)
def exporter_resultats_france(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)).scalar_one_or_none()
if not resultats_france:
resultats_france = ResultatsFranceLegislatives2024()
session.add(resultats_france)
resultats_dict = {
'zone': {
'type': "france",
'regions': [reg.code_insee for reg in session.execute(select(Region)).scalars().all()],
'departements': [dpt.code_insee for dpt in session.execute(select(Departement)).scalars().all()],
'circonscriptions': [circo.id for circo in session.execute(select(Circonscription)).scalars().all()],
'geometry': {},
},
'tour1': {
'inscrits': resultats_france.inscrits_t1,
'votants': resultats_france.votants_t1,
'abstentions': resultats_france.abstentions_t1,
'exprimes': resultats_france.exprimes_t1,
'blancs': resultats_france.blancs_t1,
'nuls': resultats_france.nuls_t1,
},
'tour2': {
'inscrits': resultats_france.inscrits_t2,
'votants': resultats_france.votants_t2,
'abstentions': resultats_france.abstentions_t2,
'exprimes': resultats_france.exprimes_t2,
'blancs': resultats_france.blancs_t2,
'nuls': resultats_france.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_nuance in resultats_france.voix:
resultats_t1[voix_nuance.nuance_id] = voix_nuance.voix_t1
resultats_t2[voix_nuance.nuance_id] = voix_nuance.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2024" / "france.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
def exporter_resultats_regions(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
regions = session.execute(select(Region)).scalars().all()
regions_json = []
regions_iterator = tqdm(regions, desc="Régions") if verbose else regions
for region in regions_iterator:
region_json = {
'type': "region",
'code_insee': region.code_insee,
'nom': region.libelle,
'departements': [dpt.code_insee for dpt in region.departements],
'circonscriptions': [
circo.id for circo in session.execute(
select(Circonscription).join(Departement).filter_by(region_code=region.code_insee))
.scalars().all()
],
'geometry': region.geometry,
}
regions_json.append(region_json)
resultats_region = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=region.code_insee)).scalar_one_or_none()
if not resultats_region:
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)).scalar_one()
resultats_region = ResultatsRegionLegislatives2024(region_id=region.code_insee,
resultats_france_id=resultats_france.id)
session.add(resultats_region)
resultats_dict = {
'zone': region_json,
'tour1': {
'inscrits': resultats_region.inscrits_t1,
'votants': resultats_region.votants_t1,
'abstentions': resultats_region.abstentions_t1,
'exprimes': resultats_region.exprimes_t1,
'blancs': resultats_region.blancs_t1,
'nuls': resultats_region.nuls_t1,
},
'tour2': {
'inscrits': resultats_region.inscrits_t2,
'votants': resultats_region.votants_t2,
'abstentions': resultats_region.abstentions_t2,
'exprimes': resultats_region.exprimes_t2,
'blancs': resultats_region.blancs_t2,
'nuls': resultats_region.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_nuance in resultats_region.voix:
resultats_t1[voix_nuance.nuance_id] = voix_nuance.voix_t1
resultats_t2[voix_nuance.nuance_id] = voix_nuance.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2024" / "region" / f"{region.code_insee}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
regions_file = DATA_DIR / "resultats" / "legislatives" / "2024" / "region" / "regions.json"
if not regions_file.parent.is_dir():
regions_file.parent.mkdir(parents=True)
with regions_file.open('w') as f:
json.dump(regions_json, f)
def exporter_resultats_departements(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
departements = session.execute(select(Departement)).scalars().all()
departements_json = []
iterator = tqdm(departements, desc="Départements") if verbose else departements
for departement in iterator:
departement_json = {
'type': "departement",
'code_insee': departement.code_insee,
'nom': departement.libelle,
'region': departement.region_code,
'circonscriptions': [circo.id for circo in departement.circonscriptions],
'communes': [commune.code_insee for commune in departement.communes],
'geometry': departement.geometry,
}
departements_json.append(departement_json)
resultats_departement = session.execute(
select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=departement.code_insee)).scalar_one_or_none()
if not resultats_departement:
resultats_region = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=departement.region_code)).scalar_one()
resultats_departement = ResultatsDepartementLegislatives2024(dpt_id=departement.code_insee,
resultats_region_id=resultats_region.id)
session.add(resultats_departement)
resultats_dict = {
'zone': departement_json,
'tour1': {
'inscrits': resultats_departement.inscrits_t1,
'votants': resultats_departement.votants_t1,
'abstentions': resultats_departement.abstentions_t1,
'exprimes': resultats_departement.exprimes_t1,
'blancs': resultats_departement.blancs_t1,
'nuls': resultats_departement.nuls_t1,
},
'tour2': {
'inscrits': resultats_departement.inscrits_t2,
'votants': resultats_departement.votants_t2,
'abstentions': resultats_departement.abstentions_t2,
'exprimes': resultats_departement.exprimes_t2,
'blancs': resultats_departement.blancs_t2,
'nuls': resultats_departement.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_nuance in resultats_departement.voix:
resultats_t1[voix_nuance.nuance_id] = voix_nuance.voix_t1
resultats_t2[voix_nuance.nuance_id] = voix_nuance.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2024" / "departement" / f"{departement.code_insee}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
departements_file = DATA_DIR / "resultats" / "legislatives" / "2024" / "departement" / "departements.json"
if not departements_file.parent.is_dir():
departements_file.parent.mkdir(parents=True)
with departements_file.open('w') as f:
json.dump(departements_json, f)
def exporter_resultats_circonscriptions(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
circonscriptions = session.execute(select(Circonscription)).scalars().all()
circonscriptions_json = []
iterator = tqdm(circonscriptions, desc="Circonscriptions") if verbose else circonscriptions
for circonscription in iterator:
circonscription_json = {
'type': "circonscription",
'id': circonscription.id,
'departement': circonscription.departement_code,
'numero': circonscription.numero,
'bureaux_vote': [bv.id for bv in circonscription.bureaux_vote],
'geometry': circonscription.geometry,
}
circonscriptions_json.append(circonscription_json)
resultats_circonscription = session.execute(
select(ResultatsCirconscriptionLegislatives2024)
.filter_by(circo_id=circonscription.id)).scalar_one_or_none()
if not resultats_circonscription:
resultats_departement = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=circonscription.departement_code)) \
.scalar_one()
resultats_circonscription = ResultatsCirconscriptionLegislatives2024(
circo_id=circonscription.id, resultats_departement_id=resultats_departement.id)
session.add(resultats_circonscription)
resultats_dict = {
'zone': circonscription_json,
'tour1': {
'inscrits': resultats_circonscription.inscrits_t1,
'votants': resultats_circonscription.votants_t1,
'abstentions': resultats_circonscription.abstentions_t1,
'exprimes': resultats_circonscription.exprimes_t1,
'blancs': resultats_circonscription.blancs_t1,
'nuls': resultats_circonscription.nuls_t1,
},
'tour2': {
'inscrits': resultats_circonscription.inscrits_t2,
'votants': resultats_circonscription.votants_t2,
'abstentions': resultats_circonscription.abstentions_t2,
'exprimes': resultats_circonscription.exprimes_t2,
'blancs': resultats_circonscription.blancs_t2,
'nuls': resultats_circonscription.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_candidat in resultats_circonscription.voix:
resultats_t1[voix_candidat.candidat.numero] = voix_candidat.voix_t1
resultats_t2[voix_candidat.candidat.numero] = voix_candidat.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2024" / "circonscription" / f"{circonscription.id}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
circonscriptions_file = (DATA_DIR / "resultats" / "legislatives" / "2024"
/ "circonscription" / "circonscriptions.json")
if not circonscriptions_file.parent.is_dir():
circonscriptions_file.parent.mkdir(parents=True)
with circonscriptions_file.open('w') as f:
json.dump(circonscriptions_json, f)
def exporter_resultats_communes(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
communes = session.execute(select(Commune)).scalars().all()
communes_json = []
iterator = tqdm(communes, desc="Communes") if verbose else communes
for commune in iterator:
commune_json = {
'type': "commune",
'code_insee': commune.code_insee,
'nom': commune.libelle,
'departement': commune.departement_code,
'bureaux_vote': [bv.id for bv in commune.bureaux_vote],
'geometry': commune.geometry,
}
communes_json.append(commune_json)
resultats_commune = session.execute(
select(ResultatsCommuneLegislatives2024).filter_by(commune_id=commune.code_insee)).scalar_one_or_none()
if not resultats_commune:
resultats_departement = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=commune.departement_code)).scalar_one()
resultats_commune = ResultatsCommuneLegislatives2024(commune_id=commune.code_insee,
resultats_dpt_id=resultats_departement.id)
session.add(resultats_commune)
resultats_dict = {
'zone': commune_json,
'tour1': {
'inscrits': resultats_commune.inscrits_t1,
'votants': resultats_commune.votants_t1,
'abstentions': resultats_commune.abstentions_t1,
'exprimes': resultats_commune.exprimes_t1,
'blancs': resultats_commune.blancs_t1,
'nuls': resultats_commune.nuls_t1,
},
'tour2': {
'inscrits': resultats_commune.inscrits_t2,
'votants': resultats_commune.votants_t2,
'abstentions': resultats_commune.abstentions_t2,
'exprimes': resultats_commune.exprimes_t2,
'blancs': resultats_commune.blancs_t2,
'nuls': resultats_commune.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_nuance in resultats_commune.voix:
resultats_t1[voix_nuance.nuance_id] = voix_nuance.voix_t1
resultats_t2[voix_nuance.nuance_id] = voix_nuance.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2024" / "commune" / f"{commune.code_insee}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
communes_file = DATA_DIR / "resultats" / "legislatives" / "2024" / "commune" / "communes.json"
if not communes_file.parent.is_dir():
communes_file.parent.mkdir(parents=True)
with communes_file.open('w') as f:
json.dump(communes_json, f)
def exporter_resultats_bureaux_vote(engine: Engine, verbose: bool = False) -> None:
with Session(engine) as session:
bureaux_vote = session.execute(select(BureauVote)).scalars().all()
bureaux_vote_json = []
iterator = tqdm(bureaux_vote, desc="Bureaux de vote") if verbose else bureaux_vote
for bureau_vote in iterator:
bureau_vote_json = {
'type': "bureau_vote",
'id': bureau_vote.id,
'libelle': bureau_vote.libelle,
'commune': bureau_vote.commune_code,
'circonscription': bureau_vote.circo_code,
'geometry': bureau_vote.geometry,
}
bureaux_vote_json.append(bureau_vote_json)
resultats_bureau_vote = session.execute(
select(ResultatsBureauVoteLegislatives2024).filter_by(bv_id=bureau_vote.id)).scalar_one_or_none()
if not resultats_bureau_vote:
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2024)
.filter_by(commune_id=bureau_vote.commune_code)).scalar_one()
resultats_bureau_vote = ResultatsBureauVoteLegislatives2024(bv_id=bureau_vote.id,
resultats_commune_id=resultats_commune.id)
session.add(resultats_bureau_vote)
resultats_dict = {
'zone': bureau_vote_json,
'tour1': {
'inscrits': resultats_bureau_vote.inscrits_t1,
'votants': resultats_bureau_vote.votants_t1,
'abstentions': resultats_bureau_vote.abstentions_t1,
'exprimes': resultats_bureau_vote.exprimes_t1,
'blancs': resultats_bureau_vote.blancs_t1,
'nuls': resultats_bureau_vote.nuls_t1,
},
'tour2': {
'inscrits': resultats_bureau_vote.inscrits_t2,
'votants': resultats_bureau_vote.votants_t2,
'abstentions': resultats_bureau_vote.abstentions_t2,
'exprimes': resultats_bureau_vote.exprimes_t2,
'blancs': resultats_bureau_vote.blancs_t2,
'nuls': resultats_bureau_vote.nuls_t2,
},
}
resultats_t1, resultats_t2 = {}, {}
resultats_dict['tour1']['voix'] = resultats_t1
resultats_dict['tour2']['voix'] = resultats_t2
for voix_candidat in resultats_bureau_vote.voix:
resultats_t1[voix_candidat.candidat.numero] = voix_candidat.voix_t1
resultats_t2[voix_candidat.candidat.numero] = voix_candidat.voix_t2
file = DATA_DIR / "resultats" / "legislatives" / "2024" / "bureau_vote" / f"{bureau_vote.id}.json"
if not file.parent.is_dir():
file.parent.mkdir(parents=True)
with file.open('w') as f:
json.dump(resultats_dict, f)
session.commit()
bureaux_vote_file = DATA_DIR / "resultats" / "legislatives" / "2024" / "bureau_vote" / "bureaux_vote.json"
if not bureaux_vote_file.parent.is_dir():
bureaux_vote_file.parent.mkdir(parents=True)
with bureaux_vote_file.open('w') as f:
json.dump(bureaux_vote_json, f)
def run(engine: Engine, verbose: bool = False) -> None:
exporter_nuances(engine, verbose)
exporter_candidats(engine, verbose)
exporter_resultats_france(engine, verbose)
exporter_resultats_regions(engine, verbose)
exporter_resultats_departements(engine, verbose)
exporter_resultats_circonscriptions(engine, verbose)
exporter_resultats_communes(engine, verbose)
exporter_resultats_bureaux_vote(engine, verbose)

View File

@ -0,0 +1,159 @@
import csv
import datetime
from sqlalchemy import Engine, select
from sqlalchemy.orm import Session
from tqdm import tqdm
from nupes.cache import get_file
from nupes.models import Genre
from nupes.models.legislatives2024 import BlocLegislatives2024, NuanceLegislatives2024, CandidatLegislatives2024
def creer_blocs(engine: Engine, verbose: bool = False) -> None:
blocs = [
{"id": 1, "nom": "Gauche", "couleur": "#BB1840"},
{"id": 2, "nom": "Droite libérale", "couleur": "#FFEB00"},
{"id": 3, "nom": "Droite conservatrice", "couleur": "#0066CC"},
{"id": 4, "nom": "Extrême droite", "couleur": "#404040"},
{"id": 5, "nom": "Autres", "couleur": "#DCBFA3"}
]
with Session(engine) as session:
for bloc_dict in blocs:
if bloc := session.execute(select(BlocLegislatives2024).filter_by(id=bloc_dict["id"])).scalar_one_or_none():
bloc.nom = bloc_dict["nom"]
bloc.couleur = bloc_dict["couleur"]
else:
session.add(BlocLegislatives2024(**bloc_dict))
session.commit()
def creer_nuances(engine: Engine, verbose: bool = False) -> None:
nuances = [
{"code": "EXG", "nom": "Extrême gauche", "couleur": "#BB0000", "bloc_id": 1},
{"code": "COM", "nom": "Parti communiste français", "couleur": "#DD0000", "bloc_id": 1},
{"code": "FI", "nom": "La France insoumise", "couleur": "#CC2443", "bloc_id": 1},
{"code": "SOC", "nom": "Parti socialiste", "couleur": "#FF8080", "bloc_id": 1},
{"code": "RDG", "nom": "Parti radical de gauche", "couleur": "#FFD1DC", "bloc_id": 1},
{"code": "UG", "nom": "Union de la gauche", "couleur": "#E4032E", "bloc_id": 1},
{"code": "VEC", "nom": "Les Écologistes", "couleur": "#00C000", "bloc_id": 1},
{"code": "DVG", "nom": "Divers gauche", "couleur": "#FFC0C0", "bloc_id": 1},
{"code": "ECO", "nom": "Écologistes", "couleur": "#77FF77", "bloc_id": 5},
{"code": "REG", "nom": "Régionalistes", "couleur": "#DCBFA3", "bloc_id": 5},
{"code": "DIV", "nom": "Divers", "couleur": "#DCDCDC", "bloc_id": 5},
{"code": "REN", "nom": "Renaissance", "couleur": "#FFEB00", "bloc_id": 2},
{"code": "ENS", "nom": "Ensemble ! (Majorité présidentielle)", "couleur": "#45B3AB", "bloc_id": 2},
{"code": "MDM", "nom": "Modem", "couleur": "#FF9900", "bloc_id": 2},
{"code": "HOR", "nom": "Horizons", "couleur": "#0001B8", "bloc_id": 2},
{"code": "DVC", "nom": "Divers centre", "couleur": "#FAC577", "bloc_id": 2},
{"code": "UDI", "nom": "Union des Démocrates et Indépendants", "couleur": "#00FFFF", "bloc_id": 3},
{"code": "LR", "nom": "Les Républicains", "couleur": "#0066CC", "bloc_id": 3},
{"code": "DVD", "nom": "Divers droite", "couleur": "#26C4EC", "bloc_id": 3},
{"code": "DSV", "nom": "Droite souverainiste", "couleur": "#8040C0", "bloc_id": 4},
{"code": "RN", "nom": "Rassemblement national", "couleur": "#0D378A", "bloc_id": 4},
{"code": "REC", "nom": "Reconquête !", "couleur": "#404040", "bloc_id": 4},
{"code": "EXD", "nom": "Extrême droite", "couleur": "#404040", "bloc_id": 4},
{"code": "UXD", "nom": "Union de l'extrême droite", "couleur": "#404040", "bloc_id": 4},
]
with Session(engine) as session:
for nuance_dict in nuances:
if nuance := session.execute(select(NuanceLegislatives2024)
.filter_by(code=nuance_dict["code"])).scalar_one_or_none():
nuance.nom = nuance_dict["nom"]
nuance.couleur = nuance_dict["couleur"]
else:
session.add(NuanceLegislatives2024(**nuance_dict))
session.commit()
def importer_candidats(engine: Engine, verbose: bool = False) -> None:
DATASET_URL = "https://www.data.gouv.fr/fr/datasets/r/cd5b39e6-5feb-4864-b274-3431ed81442c"
file = get_file(DATASET_URL, "candidats_legislatives_2024.csv")
with file.open('r') as f:
with Session(engine) as session:
reader = csv.DictReader(f, delimiter=";")
for line in tqdm(reader, desc="Candidat⋅es", disable=not verbose):
line: dict[str, str]
numero_panneau = int(line.get("Numéro de panneau"))
code_dpt = line.get("Code département").zfill(2)
match code_dpt:
case "ZA":
code_dpt = "971"
case "ZB":
code_dpt = "972"
case "ZC":
code_dpt = "973"
case "ZD":
code_dpt = "974"
case "ZS":
code_dpt = "975"
case "ZM":
code_dpt = "976"
case "ZX":
code_dpt = "977"
case "ZW":
code_dpt = "986"
case "ZP":
code_dpt = "987"
case "ZN":
code_dpt = "988"
code_circo = line.get("Code circonscription")[-2:]
circo_id = f"{code_dpt}-{code_circo}"
nuance_id = line.get("Code nuance")
nuance = session.execute(select(NuanceLegislatives2024).filter_by(code=nuance_id)).scalar_one()
if candidat := session.execute(select(CandidatLegislatives2024)
.filter_by(circonscription_id=circo_id, numero=numero_panneau)) \
.scalar_one_or_none():
candidat.nuance_id = nuance_id
candidat.bloc_id = nuance.bloc_id
candidat.nom = line['Nom du candidat']
candidat.prenom = line['Prénom du candidat']
candidat.sexe = Genre(line['Sexe du candidat'])
candidat.date_naissance = datetime.datetime.strptime(line['Date de naissance du candidat'],
"%d/%m/%Y").date()
candidat.profession = line['Profession']
candidat.sortant = line['Sortant'] == "OUI"
candidat.nom_suppleance = line['Nom remplaçant']
candidat.prenom_suppleance = line['Prénom remplaçant']
candidat.sexe_suppleance = Genre(line['Sexe remplaçant'])
candidat.date_naissance_suppleance = datetime.datetime.strptime(
line['Date de naissance remplaçant'], "%d/%m/%Y").date()
candidat.sortant = line['Sortant remplaçant'] == "OUI"
else:
candidat = CandidatLegislatives2024(
circonscription_id=circo_id,
numero=numero_panneau,
nuance_id=nuance_id,
bloc_id=nuance.bloc_id,
nom=line['Nom du candidat'],
prenom=line['Prénom du candidat'],
sexe=Genre(line['Sexe du candidat']).name,
date_naissance=datetime.datetime.strptime(line['Date de naissance du candidat'],
"%d/%m/%Y").date(),
profession=line['Profession'],
sortant=line['Sortant'] == "OUI",
nom_suppleance=line['Nom remplaçant'],
prenom_suppleance=line['Prénom remplaçant'],
sexe_suppleance=Genre(line['Sexe remplaçant']).name,
date_naissance_suppleance=datetime.datetime.strptime(line['Date de naissance remplaçant'],
"%d/%m/%Y").date(),
sortant_suppleance=line['Sortant remplaçant'] == "OUI",
)
session.add(candidat)
session.commit()
def run(engine: Engine, verbose: bool = False) -> None:
creer_blocs(engine, verbose)
creer_nuances(engine, verbose)
importer_candidats(engine, verbose)

View File

@ -0,0 +1,644 @@
import csv
from sqlalchemy import Engine, select
from sqlalchemy.orm import Session
from tqdm import tqdm
from nupes.cache import get_file
from nupes.models import BureauVote
from nupes.models.legislatives2024 import *
def importer_resultats_bv(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/6813fb28-7ec0-42ff-a528-2bc3d82d7dcd"),
(2, "https://www.data.gouv.fr/fr/datasets/r/ca974f04-cfd9-4da8-8554-4a868a09c6c2")]
with Session(engine) as session:
candidats = {(candidat.circonscription_id, candidat.numero): candidat
for candidat in session.execute(select(CandidatLegislatives2024)).scalars().all()}
bv_ids = {(bv.commune_code, bv.code_bureau): bv
for bv in session.execute(select(BureauVote)).scalars().all()}
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2024-t{tour}-par-bureau-de-vote.csv")
with file.open('r') as f:
reader = csv.DictReader(f, delimiter=';')
with Session(engine) as session:
for row in tqdm(reader, desc=f"Bureau de vote tour {tour}", disable=not verbose):
dpt_code = row['Code département']
match dpt_code:
case "ZX":
dpt_code = "977"
if dpt_code == "987" or dpt_code == "988":
# Les communes de Polynésie française ne sont pas importées
continue
com_code = row['Code commune']
if com_code == "98601":
# 3 royaumes à Wallis-et-Futuna, mais un seul résultat de commune
com_code = "98611"
if com_code.startswith("987"): # Les communes de Polynésie française ne sont pas importées
continue
bv_code = row['Code BV']
if (com_code, bv_code) not in bv_ids:
print(f"Bureau de vote {com_code}_{bv_code} non trouvé")
continue
bv = bv_ids[(com_code, bv_code)]
bv_id = bv.id
circo_id = bv.circo_code
resultats_bv = session.execute(select(ResultatsBureauVoteLegislatives2024)
.filter_by(bv_id=bv_id)).scalar_one_or_none()
if not resultats_bv:
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2024)
.filter_by(commune_id=com_code)).scalar_one_or_none()
if not resultats_commune:
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=dpt_code)) \
.scalar_one_or_none()
if not resultats_dpt:
dpt = session.execute(select(Departement).filter_by(code_insee=dpt_code)) \
.scalar_one()
resultats_reg = session.execute(
select(ResultatsRegionLegislatives2024).filter_by(region_id=dpt.region_code)) \
.scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)) \
.scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2024())
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)) \
.scalar_one()
resultats_reg = ResultatsRegionLegislatives2024(
region_id=str(dpt.region_code), resultats_france_id=resultats_france.id)
session.add(resultats_reg)
resultats_reg = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=dpt.region_code)).scalar_one()
resultats_dpt = ResultatsDepartementLegislatives2024(
dpt_id=dpt_code, resultats_region_id=resultats_reg.id)
session.add(resultats_dpt)
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=dpt_code)).scalar_one()
resultats_commune = ResultatsCommuneLegislatives2024(commune_id=com_code,
resultats_dpt_id=resultats_dpt.id)
session.add(resultats_commune)
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2024)
.filter_by(commune_id=com_code)).scalar_one()
resultats_circo = session.execute(select(ResultatsCirconscriptionLegislatives2024)
.filter_by(circo_id=circo_id)).scalar_one_or_none()
resultats_bv = ResultatsBureauVoteLegislatives2024(bv_id=bv_id,
resultats_commune_id=resultats_commune.id,
resultats_circo_id=resultats_circo.id)
session.add(resultats_bv)
resultats_bv = session.execute(select(ResultatsBureauVoteLegislatives2024)
.filter_by(bv_id=bv_id)).scalar_one()
if tour == 1:
resultats_bv.inscrits_t1 = int(row['Inscrits'])
resultats_bv.votants_t1 = int(row['Votants'])
resultats_bv.abstentions_t1 = int(row['Abstentions'])
resultats_bv.exprimes_t1 = int(row['Exprimés'])
resultats_bv.blancs_t1 = int(row['Blancs'])
resultats_bv.nuls_t1 = int(row['Nuls'])
elif tour == 2:
resultats_bv.inscrits_t2 = int(row['Inscrits'])
resultats_bv.votants_t2 = int(row['Votants'])
resultats_bv.abstentions_t2 = int(row['Abstentions'])
resultats_bv.exprimes_t2 = int(row['Exprimés'])
resultats_bv.blancs_t2 = int(row['Blancs'])
resultats_bv.nuls_t2 = int(row['Nuls'])
for i in range(1, 23):
if f'Nuance candidat {i}' not in row:
# On a épuisé toutes les nuances
break
numero = row[f'Numéro de panneau {i}']
if not numero:
continue
voix = int(row[f'Voix {i}'])
candidat = candidats[(circo_id, int(numero))]
voix_candidat_bv = session.execute(select(VoixBureauVoteLegislatives2024)
.filter_by(resultats_bureau_vote_id=resultats_bv.id,
candidat_id=candidat.id)) \
.scalar_one_or_none()
if not voix_candidat_bv:
voix_candidat_bv = VoixBureauVoteLegislatives2024(
resultats_bureau_vote_id=resultats_bv.id, candidat_id=candidat.id)
session.add(voix_candidat_bv)
if tour == 1:
voix_candidat_bv.voix_t1 = voix
elif tour == 2:
voix_candidat_bv.voix_t2 = voix
session.commit()
def importer_resultats_commune(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/bd32fcd3-53df-47ac-bf1d-8d8003fe23a1"),
(2, "https://www.data.gouv.fr/fr/datasets/r/5a8088fd-8168-402a-9f40-c48daab88cd1")]
with Session(engine) as session:
for resultats_commune in session.execute(select(ResultatsCommuneLegislatives2024)).scalars().all():
if data_round == 0 or data_round == 1:
resultats_commune.inscrits_t1 = 0
resultats_commune.votants_t1 = 0
resultats_commune.abstentions_t1 = 0
resultats_commune.exprimes_t1 = 0
resultats_commune.blancs_t1 = 0
resultats_commune.nuls_t1 = 0
if data_round == 0 or data_round == 2:
resultats_commune.inscrits_t2 = 0
resultats_commune.votants_t2 = 0
resultats_commune.abstentions_t2 = 0
resultats_commune.exprimes_t2 = 0
resultats_commune.blancs_t2 = 0
resultats_commune.nuls_t2 = 0
for voix_nuance in resultats_commune.voix:
if data_round == 0 or data_round == 1:
voix_nuance.voix_t1 = 0
if data_round == 0 or data_round == 2:
voix_nuance.voix_t2 = 0
session.commit()
com_codes = {commune.code_insee for commune in session.execute(select(Commune)).scalars().all()}
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url,
f"resultats-legislatives-2024-t{tour}-par-commune.csv")
with file.open('r') as f:
reader = csv.DictReader(f, delimiter=';')
with Session(engine) as session:
for row in tqdm(reader, desc=f"Commune tour {tour}", disable=not verbose):
dpt_code = row['Code département']
match dpt_code:
case "ZX":
dpt_code = "977"
if dpt_code == "987" or dpt_code == "988":
# Les communes de Polynésie française ne sont pas importées
continue
com_code = row['Code commune']
if com_code == "98601":
# 3 royaumes à Wallis-et-Futuna, mais un seul résultat de commune
com_code = "98611"
if com_code not in com_codes:
print(f"Commune {com_code} non trouvée")
continue
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2024)
.filter_by(commune_id=com_code)).scalar_one_or_none()
if not resultats_commune:
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=dpt_code)).scalar_one_or_none()
if not resultats_dpt:
dpt = session.execute(select(Departement)
.filter_by(code_insee=f"{dpt_code.zfill(2)}")).scalar_one()
resultats_reg = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=dpt.region_code)).scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)) \
.scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2024())
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)) \
.scalar_one()
resultats_reg = ResultatsRegionLegislatives2024(region_id=str(dpt.region_code),
resultats_france_id=resultats_france.id)
session.add(resultats_reg)
resultats_reg = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=dpt.region_code)).scalar_one()
resultats_dpt = ResultatsDepartementLegislatives2024(dpt_id=dpt_code,
resultats_region_id=resultats_reg.id)
session.add(resultats_dpt)
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=dpt_code)).scalar_one()
resultats_commune = ResultatsCommuneLegislatives2024(commune_id=com_code,
resultats_dpt_id=resultats_dpt.id)
session.add(resultats_commune)
resultats_commune = session.execute(select(ResultatsCommuneLegislatives2024)
.filter_by(commune_id=com_code)).scalar_one()
if tour == 1:
resultats_commune.inscrits_t1 += int(row['Inscrits'])
resultats_commune.votants_t1 += int(row['Votants'])
resultats_commune.abstentions_t1 += int(row['Abstentions'])
resultats_commune.exprimes_t1 += int(row['Exprimés'])
resultats_commune.blancs_t1 += int(row['Blancs'])
resultats_commune.nuls_t1 += int(row['Nuls'])
elif tour == 2:
resultats_commune.inscrits_t2 += int(row['Inscrits'])
resultats_commune.votants_t2 += int(row['Votants'])
resultats_commune.abstentions_t2 += int(row['Abstentions'])
resultats_commune.exprimes_t2 += int(row['Exprimés'])
resultats_commune.blancs_t2 += int(row['Blancs'])
resultats_commune.nuls_t2 += int(row['Nuls'])
for i in range(1, 23):
if f'Nuance candidat {i}' not in row:
# On a épuisé toutes les nuances
break
nuance_code = row[f'Nuance candidat {i}']
if not nuance_code:
continue
voix = int(row[f'Voix {i}'])
voix_nuance_commune = session.execute(select(VoixCommuneLegislatives2024)
.filter_by(resultats_commune_id=resultats_commune.id,
nuance_id=nuance_code)) \
.scalar_one_or_none()
if not voix_nuance_commune:
voix_nuance_commune = VoixCommuneLegislatives2024(resultats_commune_id=resultats_commune.id,
nuance_id=nuance_code,
voix_t1=0, voix_t2=0)
session.add(voix_nuance_commune)
if tour == 1:
voix_nuance_commune.voix_t1 += voix
elif tour == 2:
voix_nuance_commune.voix_t2 += voix
session.commit()
def importer_resultats_circo(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/5163f2e3-1362-4c35-89a0-1934bb74f2d9"),
(2, "https://www.data.gouv.fr/fr/datasets/r/41ed46cd-77c2-4ecc-b8eb-374aa953ca39")]
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2024-t{tour}-par-circonscription.csv")
with file.open('r') as f:
reader = csv.DictReader(f, delimiter=';')
with Session(engine) as session:
for row in tqdm(reader, desc=f"Circonscription tour {tour}", disable=not verbose):
dpt_code = row['Code département']
circo_code = row['Code circonscription législative'][-2:]
match dpt_code:
case "ZX":
dpt_code = "977"
circo_id = f"{dpt_code.zfill(2)}-{circo_code.zfill(2)}"
resultats_circo = session.execute(select(ResultatsCirconscriptionLegislatives2024)
.filter_by(circo_id=circo_id)).scalar_one_or_none()
if not resultats_circo:
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=dpt_code)).scalar_one_or_none()
if not resultats_dpt:
dpt = session.execute(select(Departement).filter_by(code_insee=f"{dpt_code.zfill(2)}")) \
.scalar_one()
resultats_reg = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=dpt.region_code)) \
.scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)) \
.scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2024())
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)).scalar_one()
resultats_reg = ResultatsRegionLegislatives2024(region_id=str(dpt.region_code),
resultats_france_id=resultats_france.id)
session.add(resultats_reg)
resultats_reg = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=dpt.region_code)).scalar_one()
resultats_dpt = ResultatsDepartementLegislatives2024(dpt_id=dpt_code,
resultats_region_id=resultats_reg.id)
session.add(resultats_dpt)
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=dpt_code)).scalar_one()
resultats_circo = ResultatsCirconscriptionLegislatives2024(
circo_id=circo_id, resultats_departement_id=resultats_dpt.id)
session.add(resultats_circo)
resultats_circo = session.execute(select(ResultatsCirconscriptionLegislatives2024)
.filter_by(circo_id=circo_id)).scalar_one()
if tour == 1:
resultats_circo.inscrits_t1 = int(row['Inscrits'])
resultats_circo.votants_t1 = int(row['Votants'])
resultats_circo.abstentions_t1 = int(row['Abstentions'])
resultats_circo.exprimes_t1 = int(row['Exprimés'])
resultats_circo.blancs_t1 = int(row['Blancs'])
resultats_circo.nuls_t1 = int(row['Nuls'])
elif tour == 2:
resultats_circo.inscrits_t2 = int(row['Inscrits'])
resultats_circo.votants_t2 = int(row['Votants'])
resultats_circo.abstentions_t2 = int(row['Abstentions'])
resultats_circo.exprimes_t2 = int(row['Exprimés'])
resultats_circo.blancs_t2 = int(row['Blancs'])
resultats_circo.nuls_t2 = int(row['Nuls'])
for i in range(1, 23):
if f'Nuance candidat {i}' not in row:
# On a épuisé toutes les nuances
break
numero = row[f'Numéro de panneau {i}']
if not numero:
continue
voix = int(row[f'Voix {i}'])
candidat = session.execute(select(CandidatLegislatives2024)
.filter_by(circonscription_id=circo_id, numero=numero)) \
.scalar_one_or_none()
voix_candidat_circo = session.execute(select(VoixCirconscriptionLegislatives2024)
.filter_by(resultats_circonscription_id=resultats_circo.id,
candidat_id=candidat.id)) \
.scalar_one_or_none()
if not voix_candidat_circo:
voix_candidat_circo = VoixCirconscriptionLegislatives2024(
resultats_circonscription_id=resultats_circo.id, candidat_id=candidat.id)
session.add(voix_candidat_circo)
if tour == 1:
voix_candidat_circo.voix_t1 = voix
elif tour == 2:
voix_candidat_circo.voix_t2 = voix
session.commit()
def importer_resultats_departement(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/78c708c5-5bc5-438d-8379-f432beae3f2b"),
(2, "https://www.data.gouv.fr/fr/datasets/r/8d4a6927-c96f-4cf5-b757-ea745eca26bd")]
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2024-t{tour}-par-departement.csv")
with file.open('r') as f:
reader = csv.DictReader(f, delimiter=';')
with Session(engine) as session:
for row in tqdm(reader, desc=f"Département tour {tour}", disable=not verbose):
dpt_code = row['Code département']
match dpt_code:
case "ZX":
dpt_code = "977"
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=dpt_code)).scalar_one_or_none()
if not resultats_dpt:
dpt = session.execute(select(Departement)
.filter_by(code_insee=f"{dpt_code.zfill(2)}")) \
.scalar_one()
resultats_reg = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=dpt.region_code)) \
.scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)) \
.scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2024())
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)).scalar_one()
resultats_reg = ResultatsRegionLegislatives2024(region_id=str(dpt.region_code),
resultats_france_id=resultats_france.id)
session.add(resultats_reg)
resultats_reg = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=dpt.region_code)).scalar_one()
resultats_dpt = ResultatsDepartementLegislatives2024(dpt_id=dpt_code,
resultats_region_id=resultats_reg.id)
session.add(resultats_dpt)
resultats_dpt = session.execute(select(ResultatsDepartementLegislatives2024)
.filter_by(dpt_id=dpt_code)).scalar_one()
if tour == 1:
resultats_dpt.inscrits_t1 = int(row['Inscrits'])
resultats_dpt.votants_t1 = int(row['Votants'])
resultats_dpt.abstentions_t1 = int(row['Abstentions'])
resultats_dpt.exprimes_t1 = int(row['Exprimés'])
resultats_dpt.blancs_t1 = int(row['Blancs'])
resultats_dpt.nuls_t1 = int(row['Nuls'])
elif tour == 2:
resultats_dpt.inscrits_t2 = int(row['Inscrits'])
resultats_dpt.votants_t2 = int(row['Votants'])
resultats_dpt.abstentions_t2 = int(row['Abstentions'])
resultats_dpt.exprimes_t2 = int(row['Exprimés'])
resultats_dpt.blancs_t2 = int(row['Blancs'])
resultats_dpt.nuls_t2 = int(row['Nuls'])
for i in range(1, 23):
if f'Nuance candidat {i}' not in row:
# On a épuisé toutes les nuances
break
nuance_code = row[f'Nuance candidat {i}']
if not nuance_code:
continue
voix = int(row[f'Voix {i}'])
voix_nuance_dpt = session.execute(select(VoixDepartementLegislatives2024)
.filter_by(resultats_departement_id=resultats_dpt.id,
nuance_id=nuance_code)) \
.scalar_one_or_none()
if not voix_nuance_dpt:
voix_nuance_dpt = VoixDepartementLegislatives2024(resultats_departement_id=resultats_dpt.id,
nuance_id=nuance_code)
session.add(voix_nuance_dpt)
if tour == 1:
voix_nuance_dpt.voix_t1 = voix
elif tour == 2:
voix_nuance_dpt.voix_t2 = voix
session.commit()
def importer_resultats_region(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
tours = [(1, "https://www.data.gouv.fr/fr/datasets/r/f69ffab7-fe37-494e-ad6d-a7cfc80ddc1f"),
(2, "https://www.data.gouv.fr/fr/datasets/r/ac4e272a-3ce2-4f20-941e-fb0ded444a5d")]
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2024-t{tour}-par-region.csv")
with file.open('r') as f:
reader = csv.DictReader(f, delimiter=';')
with Session(engine) as session:
for row in tqdm(reader, desc=f"Région tour {tour}", disable=not verbose):
reg_code = row['Code région']
resultats_reg = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=reg_code)).scalar_one_or_none()
if not resultats_reg:
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)).scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2024())
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)).scalar_one()
resultats_reg = ResultatsRegionLegislatives2024(region_id=reg_code,
resultats_france_id=resultats_france.id)
session.add(resultats_reg)
session.commit()
resultats_reg = session.execute(select(ResultatsRegionLegislatives2024)
.filter_by(region_id=reg_code)).scalar_one()
if tour == 1:
resultats_reg.inscrits_t1 = int(row['Inscrits'])
resultats_reg.votants_t1 = int(row['Votants'])
resultats_reg.abstentions_t1 = int(row['Abstentions'])
resultats_reg.exprimes_t1 = int(row['Exprimés'])
resultats_reg.blancs_t1 = int(row['Blancs'])
resultats_reg.nuls_t1 = int(row['Nuls'])
elif tour == 2:
resultats_reg.inscrits_t2 = int(row['Inscrits'])
resultats_reg.votants_t2 = int(row['Votants'])
resultats_reg.abstentions_t2 = int(row['Abstentions'])
resultats_reg.exprimes_t2 = int(row['Exprimés'])
resultats_reg.blancs_t2 = int(row['Blancs'])
resultats_reg.nuls_t2 = int(row['Nuls'])
for i in range(1, 23):
if f'Nuance candidat {i}' not in row:
# On a épuisé toutes les nuances
break
nuance_code = row[f'Nuance candidat {i}']
if not nuance_code:
continue
voix = int(row[f'Voix {i}'])
voix_nuance_reg = session.execute(select(VoixRegionLegislatives2024)
.filter_by(resultats_region_id=resultats_reg.id,
nuance_id=nuance_code)) \
.scalar_one_or_none()
if not voix_nuance_reg:
voix_nuance_reg = VoixRegionLegislatives2024(resultats_region_id=resultats_reg.id,
nuance_id=nuance_code)
session.add(voix_nuance_reg)
if tour == 1:
voix_nuance_reg.voix_t1 = voix
elif tour == 2:
voix_nuance_reg.voix_t2 = voix
session.commit()
def importer_resultats_france(engine: Engine, data_round: int = 0, verbose: bool = False) -> None:
# Erreur avec les données France Entière du 1er tour, qui sera j'espère corrigée un jour
tours = [# (1, "https://www.data.gouv.fr/fr/datasets/r/386fd5ac-e7f1-4e0f-8929-12d2c5391081"),
(2, "https://www.data.gouv.fr/fr/datasets/r/f64d2781-4ffa-414b-8f6d-e9d849f2f5e7")]
for tour, file_url in tours:
if data_round > 0 and tour != data_round:
# On saute ce tour
continue
file = get_file(file_url, f"resultats-legislatives-2024-t{tour}-france-entiere.csv")
with file.open('r') as f:
reader = csv.DictReader(f, delimiter=';')
with Session(engine) as session:
for row in tqdm(reader, desc=f"France Entière tour {tour}", disable=not verbose):
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)).scalar_one_or_none()
if not resultats_france:
session.add(ResultatsFranceLegislatives2024())
session.commit()
resultats_france = session.execute(select(ResultatsFranceLegislatives2024)).scalar_one()
if tour == 1:
resultats_france.inscrits_t1 = int(row['Inscrits'])
resultats_france.votants_t1 = int(row['Votants'])
resultats_france.abstentions_t1 = int(row['Abstentions'])
resultats_france.exprimes_t1 = int(row['Exprimés'])
resultats_france.blancs_t1 = int(row['Blancs'])
resultats_france.nuls_t1 = int(row['Nuls'])
elif tour == 2:
resultats_france.inscrits_t2 = int(row['Inscrits'])
resultats_france.votants_t2 = int(row['Votants'])
resultats_france.abstentions_t2 = int(row['Abstentions'])
resultats_france.exprimes_t2 = int(row['Exprimés'])
resultats_france.blancs_t2 = int(row['Blancs'])
resultats_france.nuls_t2 = int(row['Nuls'])
for i in range(1, 23):
if f'Nuance candidat {i}' not in row:
# On a épuisé toutes les nuances
break
nuance_code = row[f'Nuance candidat {i}']
voix = int(row[f'Voix {i}'])
voix_nuance_france = session.execute(select(VoixFranceLegislatives2024)
.filter_by(resultats_france_id=resultats_france.id,
nuance_id=nuance_code)) \
.scalar_one_or_none()
if not voix_nuance_france:
voix_nuance_france = VoixFranceLegislatives2024(resultats_france_id=resultats_france.id,
nuance_id=nuance_code)
session.add(voix_nuance_france)
if tour == 1:
voix_nuance_france.voix_t1 = voix
elif tour == 2:
voix_nuance_france.voix_t2 = voix
session.commit()
def run(engine: Engine, data_round: int = 1, verbose: bool = False) -> None:
importer_resultats_france(engine, data_round, verbose)
importer_resultats_region(engine, data_round, verbose)
importer_resultats_departement(engine, data_round, verbose)
importer_resultats_circo(engine, data_round, verbose)
importer_resultats_commune(engine, data_round, verbose)
importer_resultats_bv(engine, data_round, verbose)