Outils pour utilisateurs

Outils du site


dev:python:flask:flask-sqlalchemy:relation_agregation

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
dev:python:flask:flask-sqlalchemy:relation_agregation [2025/07/22 10:05] – créée yoanndev:python:flask:flask-sqlalchemy:relation_agregation [2025/07/22 15:31] (Version actuelle) yoann
Ligne 1: Ligne 1:
 {{tag>dev python sql sqlalchemy relation}} {{tag>dev python sql sqlalchemy relation}}
  
-:TODO_DOCUPDATE: 
  
 ====== Flask-SQLAlchemy : Définir une relation d'agrégation ====== ====== Flask-SQLAlchemy : Définir une relation d'agrégation ======
Ligne 15: Ligne 14:
  
  
-Un entrepôt (Warehouse) peut stocker plusieurs colis (Packet), et un colis est entreposé dans un seul entrepôt : cela définit bien une relation un à plusieurs (one to many).+Un entrepôt (Warehouse) peut stocker plusieurs colis (Packet), et un colis est entreposé dans un seul entrepôt : cela définit bien une association un à plusieurs (one to many).
  
  
-En définissant une relation de type agréation, **on fait le choix** de conserver les colis dans notre base de données même si on supprime notre entrepôt.+En définissant une association de type agréation, **on fait le choix** de conserver les colis dans notre base de données même si on supprime notre entrepôt.
  
  
-===== MLD et contraintes =====+===== MLD et création des contraintes =====
  
 Pour pouvoir traduire cette relation d'agrégation il va falloir créer les contraintes appropriées lors de l'étape de traduction vers les MLD/MPD. Pour pouvoir traduire cette relation d'agrégation il va falloir créer les contraintes appropriées lors de l'étape de traduction vers les MLD/MPD.
Ligne 27: Ligne 26:
 {{mld_relation_agregation.png}} {{mld_relation_agregation.png}}
  
 +Le détail des règles de traduction des associations dans le MLD est abordé dans le cours [[cours:informatique:dev:db:modeliser_bases_de_donnees:340_transformer_associations_du_diagramme_de_classes|Transformez les associations de votre diagramme de classes UML]]. Ici on ajoute une clé étrangère à la relation (table)  "packet".
  
-Avec SQLAlchemy, il nous faudra définir la relation et un cascade update 
  
-Ci-dessous une application minimale Flask définissant le modèle de données+Ci-dessous une application minimale Flask mettant en œuvre le modèle de données.
  
-<code python>+<code python app.py [enable_line_numbers="true", highlight_lines_extra="19,20"]> 
 +from flask import Flask 
 +from flask_sqlalchemy import SQLAlchemy 
 +  
 +db = SQLAlchemy() 
 +  
 +  
 +class Warehouse(db.Model): 
 +    __tablename__ = 'warehouse' 
 +    id = db.Column(db.Integer, primary_key=True, index=True) 
 +    name = db.Column(db.String(80), unique=True, index=True) 
 + 
  
 + 
 +class Packet(db.Model):
 +    __tablename__ = 'packet'
 +    id = db.Column(db.Integer, primary_key=True, index=True)
 +    sender = db.Column(db.String(80))
 +    recipient = db.Column(db.String(80))
 +    warehouse_id = db.Column(db.Integer, db.ForeignKey('warehouse.id'), unique=False, nullable=True)
 +    warehouse = db.relationship("Warehouse", backref="packets")
 + 
 +
 +app = Flask(__name__)
 + 
 +# Le chemin vers la base SQLite est relatif au dossier de l'application flask
 +app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
 + 
 +# Initialiser l'application Flask par l'intermédiaire de l'extension
 +db.init_app(app)
  
 </code> </code>
 +
 +Deux point importants à relever :
 +  * À la ligne 19 on **définit la clé étrangère** avec l'option **''nullable=True''** cela permet au SGDB de remplacer la clé primaire de l’entrepôt par la valeur null lorsque l'entrepôt lié est supprimé.
 +  * À la ligne 20 on définit l'association entre Warehouse et Packet : le premier argument permet de spécifier le nom de la classe liée et le second permet de définir l'attribut de rappel ainsi ''Packet.warehouse'' permettra de retrouver l’entrepôt lié au colis par cette association.
 +
 +
 +
 +On peut tester rapidement le comportement du modèle avec la commande **flask shell** (mode interactif dans le contexte de l'application Flask).
 +
 +
 +<code python>
 +>>> # Reinitialisation de la base
 +>>> db.drop_all()
 +>>> db.create_all()
 +>>>
 +>>> # Création d'un entrepôt
 +>>> repo = Warehouse(name="CentralRepository")
 +>>> 
 +>>> # Création de 3 colis déposés dans cet entrepôt
 +>>> p1 = Packet(sender="Yoann", recipient="Mariel", warehouse=repo)
 +>>> p2 = Packet(sender="Annie", recipient="Nathalie", warehouse=repo)
 +>>> p3 = Packet(sender="Emilie", recipient="Bastien", warehouse=repo)
 +>>> 
 +>>> # Enregistre dans la base
 +>>> db.session.add_all([repo, p1, p2, p3])
 +>>> db.session.commit()
 +>>>
 +>>> # Récupère et affiche les colis
 +>>> packets = Packet.query.all()
 +>>> for packet in packets :
 +...   print(f"<Packet {packet.id} sender={packet.sender} recipient={packet.recipient}> in {packet.warehouse.name}>")
 +... 
 +<Packet 1 sender=Yoann recipient=Mariel> in CentralRepository>
 +<Packet 2 sender=Annie recipient=Nathalie> in CentralRepository>
 +<Packet 3 sender=Emilie recipient=Bastien> in CentralRepository>
 +>>>
 +>>> # Supprimer l'entrepôt
 +>>> db.session.delete(repo)
 +>>> db.session.commit()
 +>>> del repo
 +>>>
 +>>> # On récupère un colis et on affiche l’entrepôt lié
 +>>> packet = Packet.query.first()
 +>>> print(packet.warehouse)
 +None
 +</code>
 +
 +
 +Pour automatiser les tests on pourra s’appuyer sur  pytest 
  
  
dev/python/flask/flask-sqlalchemy/relation_agregation.1753178752.txt.gz · Dernière modification : 2025/07/22 10:05 de yoann