Configuration des modèles de base de données

Configuration d’un nouveau modèle

Un modèle est une classe héritant de DBBASE ou d’un autre modèle dans le cas du polymorphisme (voir la section dédiée).

Elle doit également

  • préciser le nom de la table (nom de la classe en minuscule en préfixant les majuscules intermédiaires par des _)

  • spécifier des options communes (encoding notamment)

  • disposer d’une primary_key (dans enDI cette primary key se nomme id par convention).

from endi_base.models.base import DBBASE

class MonModele(DBBASE):
    __tablename__ = "mon_modele"
    __table_args__ = default_table_args
    id = Column(Integer, primary_key=True)

Configuration des relations

Ce chapitre décrit comment configurer correctement les relations entre modèles.

OneToMany

Une relation O2M ou parent-enfants se configure

  • Au travers d’une ForeignKey permet d’associer un enfant à son parent (méthode classique au sens SQL).

  • Les relations déclarées qui vont permettre d’accéder au modèle lié depuis une instance du modèle. Ces déclarations vont également indiquer à SQLAlchemy comment mettre à jour les données durant le temps de traitement de la transaction courante.

L’exemple ci-dessous montre une implémentation.

NB : dans enDI nous utilisons back_populates. Nous n’utilisons pas l’attribut backref de l’outil « relationship » afin d’éviter la création implicite d’attribut.

class BusinessPaymentDeadline(DBBASE):
    ...
    business_id = Column(Integer, ForeignKey("business.id"))
    business = relationship("Business", back_populates="payment_deadlines")

class Business(DBBASE):
    ...
    payment_deadlines = relationship(
        "BusinessPaymentDeadline",
        primaryjoin="BusinessPaymentDeadline.business_id==Business.id",
        back_populates="business"
    )

Si la suppression d’un élément doit entrainer la suppression des objets qui lui sont liés, on précisera cela :

  • Au niveau de la ForeignKey (ondelete= »CASCADE »)

  • Au niveau de la relation parent-> enfant (cascade= »all delete-orphan »)

class BusinessPaymentDeadline(DBBASE):
    ...
    business_id = Column(Integer, ForeignKey("business.id", ondelete="CASCADE"))
    business = relationship("Business", back_populates="payment_deadlines")

class Business(DBBASE):
    ...
    payment_deadlines = relationship(
        "BusinessPaymentDeadline",
        primaryjoin="BusinessPaymentDeadline.business_id==Business.id",
        cascade="all, delete-orphan",
        back_populates="business"
    )