SQLAlchemy ORM - Déclaration de mappage

L'objectif principal de l'API Object Relational Mapper de SQLAlchemy est de faciliter l'association de classes Python définies par l'utilisateur avec des tables de base de données et des objets de ces classes avec des lignes dans leurs tables correspondantes. Les changements d'état des objets et des lignes sont mis en correspondance de manière synchrone. SQLAlchemy permet d'exprimer des requêtes de base de données en termes de classes définies par l'utilisateur et de leurs relations définies.

L'ORM est construit au-dessus du langage d'expression SQL. Il s'agit d'un modèle d'utilisation abstrait et de haut niveau. En fait, ORM est une utilisation appliquée du langage d'expression.

Bien qu'une application réussie puisse être construite à l'aide de l'Object Relational Mapper exclusivement, une application construite avec l'ORM peut parfois utiliser le langage d'expression directement là où des interactions de base de données spécifiques sont requises.

Déclarer le mappage

Tout d'abord, la fonction create_engine () est appelée pour configurer un objet moteur qui est ensuite utilisé pour effectuer des opérations SQL. La fonction a deux arguments, l'un est le nom de la base de données et l'autre est un paramètre d'écho lorsqu'il est défini sur True, il génère le journal d'activité. S'il n'existe pas, la base de données sera créée. Dans l'exemple suivant, une base de données SQLite est créée.

from sqlalchemy import create_engine
engine = create_engine('sqlite:///sales.db', echo = True)

Le moteur établit une véritable connexion DBAPI à la base de données lorsqu'une méthode comme Engine.execute () ou Engine.connect () est appelée. Il est ensuite utilisé pour émettre le SQLORM qui n'utilise pas directement le moteur; au lieu de cela, il est utilisé dans les coulisses par l'ORM.

Dans le cas de l'ORM, le processus de configuration commence par la description des tables de la base de données, puis par la définition des classes qui seront mappées à ces tables. Dans SQLAlchemy, ces deux tâches sont effectuées ensemble. Ceci est fait en utilisant le système déclaratif; les classes créées incluent des directives pour décrire la table de base de données réelle à laquelle elles sont mappées.

Une classe de base stocke un catlog de classes et de tables mappées dans le système déclaratif. Cela s'appelle la classe de base déclarative. Il n'y aura généralement qu'une seule instance de cette base dans un module couramment importé. La fonction déclarative_base () est utilisée pour créer la classe de base. Cette fonction est définie dans le module sqlalchemy.ext.declarative.

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

Une fois la classe de base déclarée, n'importe quel nombre de classes mappées peut être défini en fonction de celle-ci. Le code suivant définit la classe d'un client. Il contient la table à mapper, ainsi que les noms et les types de données des colonnes.

class Customers(Base):
   __tablename__ = 'customers'
   
   id = Column(Integer, primary_key = True)
   name = Column(String)
   address = Column(String)
   email = Column(String)

Une classe dans Declarative doit avoir un __tablename__ attribut, et au moins un Columnqui fait partie d'une clé primaire. Déclaratif remplace tous lesColumn objets avec des accesseurs Python spéciaux appelés descriptors. Ce processus est appelé instrumentation qui permet de faire référence à la table dans un contexte SQL et permet de conserver et de charger les valeurs des colonnes à partir de la base de données.

Cette classe mappée comme une classe Python normale a des attributs et des méthodes selon l'exigence.

Les informations sur la classe dans le système déclaratif sont appelées comme métadonnées de table. SQLAlchemy utilise l'objet Table pour représenter ces informations pour une table spécifique créée par Declarative. L'objet Table est créé selon les spécifications et est associé à la classe en construisant un objet Mapper. Cet objet mappeur n'est pas utilisé directement mais est utilisé en interne comme interface entre la classe mappée et la table.

Chaque objet Table est membre d'une plus grande collection connue sous le nom de MetaData et cet objet est disponible à l'aide de la .metadataattribut de la classe de base déclarative. leMetaData.create_all()est, en passant dans notre moteur comme une source de connectivité de base de données. Pour toutes les tables qui n'ont pas encore été créées, il émet des instructions CREATE TABLE vers la base de données.

Base.metadata.create_all(engine)

Le script complet pour créer une base de données et une table, et pour mapper la classe Python est donné ci-dessous -

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Customers(Base):
   __tablename__ = 'customers'
   id = Column(Integer, primary_key=True)

   name = Column(String)
   address = Column(String)
   email = Column(String)
Base.metadata.create_all(engine)

Lorsqu'elle est exécutée, la console Python fera écho après l'exécution de l'expression SQL -

CREATE TABLE customers (
   id INTEGER NOT NULL,
   name VARCHAR,
   address VARCHAR,
   email VARCHAR,
   PRIMARY KEY (id)
)

Si nous ouvrons le Sales.db à l'aide de l'outil graphique SQLiteStudio, il affiche la table des clients à l'intérieur avec la structure mentionnée ci-dessus.