Code source de services.api_ihm.src.database.models

"""
Version: 1.1.0 (2024-12-20)
Auteur: Kahina et franck - Groupe 2
Commit: bigmoletos@yopmail.com

Modèles de données SQLAlchemy pour l'application de qualité de l'air.

Ce module définit les modèles de données pour la persistance des informations
dans la base de données SQLite. Il gère :
- Les utilisateurs et leur authentification
- L'historique des simulations de qualité de l'air
- Les relations entre utilisateurs et simulations

Architecture:
------------
1. Gestion des utilisateurs:
   - Authentification sécurisée avec hachage des mots de passe
   - Support des rôles (admin/utilisateur)
   - Profils utilisateurs avec email unique

2. Historique des simulations:
   - Stockage des paramètres d'entrée
   - Enregistrement des résultats
   - Horodatage automatique
   - Liaison avec l'utilisateur

3. Relations et contraintes:
   - Clés étrangères pour l'intégrité référentielle
   - Contraintes d'unicité sur username/email
   - Cascade de suppression des simulations

Classes:
--------
    User: Modèle utilisateur avec authentification
    Simulation: Historique des prédictions

Dépendances:
-----------
    - flask_sqlalchemy : ORM SQL
    - flask_login : Gestion de l'authentification
    - werkzeug.security : Hachage des mots de passe
"""
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime

db = SQLAlchemy()


[docs] class User(UserMixin, db.Model): """ Modèle utilisateur pour l'authentification et la gestion des droits. Attributes: ---------- id : int Identifiant unique auto-incrémenté username : str Nom d'utilisateur unique email : str Adresse email unique password_hash : str Hash du mot de passe is_admin : bool Indique si l'utilisateur est administrateur simulations : list Liste des simulations de l'utilisateur """ __tablename__ = 'user' # Nom explicite de la table id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64, collation='NOCASE'), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False, index=True) password_hash = db.Column(db.String(128)) is_admin = db.Column(db.Boolean, default=False, nullable=False) simulations = db.relationship('Simulation', backref='user', lazy=True) def __repr__(self): return f'<User {self.username}>'
[docs] def set_password(self, password): self.password_hash = generate_password_hash(password)
[docs] def check_password(self, password): return check_password_hash(self.password_hash, password)
[docs] class Simulation(db.Model): """ Modèle pour l'historique des simulations de qualité de l'air. Cette classe stocke les données et résultats des simulations avec: - Horodatage automatique - Stockage des paramètres d'entrée en JSON - Liaison avec l'utilisateur ayant effectué la simulation - Support des requêtes et filtres Attributes: ---------- id : int Identifiant unique auto-incrémenté user_id : int ID de l'utilisateur (clé étrangère) date : datetime Date et heure de la simulation (UTC) input_data : JSON Paramètres d'entrée de la simulation Format: { "TEMP": float, "DEWP": float, "PRES": float, "cbwd": str, ... } result : float Résultat de la prédiction (PM2.5) Methods: ------- __repr__() Représentation string de la simulation Version: 1.0.0 (2024-03-19 15:35) """ id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) date = db.Column(db.DateTime, default=datetime.utcnow) input_data = db.Column(db.JSON) result = db.Column(db.Float) def __repr__(self): return f'<Simulation {self.id} by User {self.user_id} on {self.date}>'
[docs] def add_is_admin_column(): """ Ajoute la colonne is_admin à la table user si elle n'existe pas. Cette fonction est utilisée pour la migration de la base de données. Elle vérifie d'abord si la colonne existe avant de l'ajouter pour éviter les erreurs. Raises: ------ SQLAlchemyError En cas d'erreur lors de la modification de la table Notes: ----- - Utilise des requêtes SQL brutes via SQLAlchemy text() - La colonne est ajoutée avec une valeur par défaut False - La transaction est automatiquement rollback en cas d'erreur """ from sqlalchemy import text try: # Vérifier si la colonne existe db.session.execute(text('SELECT is_admin FROM user LIMIT 1')) logger.info("La colonne is_admin existe déjà") except Exception: logger.info("Ajout de la colonne is_admin") db.session.execute( text('ALTER TABLE user ADD COLUMN is_admin BOOLEAN DEFAULT FALSE')) db.session.commit()
""" Modèles de données SQLAlchemy pour l'application. Version: 1.0.0 (2024-03-19 15:35) Ce module définit les modèles de données pour : - La gestion des utilisateurs - L'historique des simulations - Les relations entre les modèles Classes: User: Modèle utilisateur avec authentification Simulation: Historique des prédictions """