Outils pour utilisateurs

Outils du site


dev:python:flask:flask-sqlalchemy:relation_one-to-many

Flask-SQLAlchemy : relation one-to-many

Quelques notes à propos de l'implémentation d'une relation un à plusieurs (one to many) avec l'extension Flask-SQLAlchemy.

Pour illustrer le concept on prend un exemple rudimentaire :

MCD via diagramme UML

  • Un magasin (Shop) vend un ou plusieurs produits (Product);
  • Un produit est vendu par un seul magasin.

Implémentation

Ci-dessous l'application Flask minimaliste implémentant les deux classes du modèle et la relation one-to-many.

app.py
  1. from flask import Flask
  2. from flask_sqlalchemy import SQLAlchemy
  3.  
  4. db = SQLAlchemy()
  5.  
  6.  
  7. class Shop(db.Model):
  8. __tablename__ = 'shops'
  9. id = db.Column(db.Integer, primary_key=True, index=True)
  10. name = db.Column(db.String(80), unique=True, index=True)
  11.  
  12. products = db.relationship("Product", back_populates="shop", lazy='dynamic')
  13.  
  14. def add_product(self, product):
  15. if self.id is None :
  16. # Le magasin doit exister en base avant d'ajouter un produit
  17. db.session.add(self)
  18. db.session.commit()
  19.  
  20. product.shop_id = self.id
  21. db.session.add(product)
  22. db.session.commit()
  23.  
  24.  
  25. class Product(db.Model):
  26. __tablename__ = 'products'
  27. id = db.Column(db.Integer, primary_key=True, index=True)
  28. name = db.Column(db.String(80), unique=True, index=True)
  29. price = db.Column(db.Float(precision=2))
  30.  
  31. shop_id = db.Column(db.Integer, db.ForeignKey('shops.id'), unique=False, nullable=False)
  32.  
  33. shop = db.relationship("Shop", back_populates="products")
  34.  
  35.  
  36.  
  37. # Création de l'application
  38. # On utilise la variable __name__ pour définir le nom du module courant
  39. # comme root applicatif pour notre application flask
  40. app = Flask(__name__)
  41.  
  42. # Le chemin vers la base SQLite est relatif au dossier de l'application flask
  43. app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
  44.  
  45. # Initialiser l'application Flask par l'intermédiaire de l'extension
  46. db.init_app(app)

:TODO_DOCUPDATE:

  • Lignes 7 et 27 : les classes doivent hériter de db.Model pour que les objets puissent être enrgistrés dans la bbase de données;
  • Pour chaque attribut on définit sous quelle forme il sera stocké dans la base;

La relation one-to-many

L'option lazy="dynamic" de la méthode db.relationship

A la ligne 12, on peut voir que l'option lazy=“dynamic” est utilisée pour définir la relation.

Lorsque cette option est utilisée, l'attribut Shop.products ne retourne plus directement la liste complète de tous les produits désignés par la relation. Au lieu de cela, Shop.products retourne un objet de type requête : cela permet notamment de définir des critères de sélection.

Test et utilisation

Pour tester l'implémentation, on peut lancer l'application flask en mode interactif :

flask shell
>>> # Afficher les références
 
 
>>> # Création de la base
 
 
>>> # Instanciation d'un magasin et de quelques produits
 
 
 
>>> # Ne récupérer que les produits dont le prix est supérieur à 30€
>>> rqt.filter(Product.price>30.0).all()
 
>>> # Utilisation de la fonction LIKE
>>> rqt.filter(Product.name.like('%Ri%')).all()

Références

dev/python/flask/flask-sqlalchemy/relation_one-to-many.txt · Dernière modification : 2024/12/07 13:57 de yoann