Python SQLAlchemy

SQLAlchemy és una biblioteca de Python de codi obert, que permet la interacció amb bases de dades relacionals SQL. Proporciona una capa d'abstracció amb els diferents motors de bases de dades, el que permet que el codi sigui independent al gestor de base dades que es faci servir.

Habitual en l'ús de desenvolupament de pàgines web. La principal característica de SQLAlchemy és un ORM (Object-Relational Mapping), que permet mapejar les taules de les base de dades a classes de Python (models) i amb el que es permet treballar amb objectes i mètodes com si fos una base de dades orientada a objectes.

La documentació de SQLAlchemy es troba a:Web Oficial.

Per poder treballar amb SQLAlchemy necessitarem:

* Python versió 3.10 o superior (depenent en el moment de lectura tindrem una versió superior a la 3.10) * Llibreria SQLAlchemy * Gestor de base de dades (MySQL, MariaDB, SQLite, PostgrSQL, altres)

Per instal·lar la llibreria de SQLAlchemy (Si teniu un entorn virtual feu-lo servir), teniu també SQLAlchemy-Utils que permet fer la creació de base de dades, eliminar i altres funcionalitats Documentació oficial.

$ pip install sqlalchemy

$ pip install SQLAlchemy-Utils

El següents exemples es basaran en una connexió mitjançant MySQL.

Crearem una base de dades anomenada testpy a MySQL. Podeu fer servir el gestor que vulgueu. És importat que SQLAlchemy no crea la base de dades per això podeu crear la base de dades que es posa a continuació:

DROP DATABASE IF EXISTS testpy;
 
CREATE DATABASE testpy;
 
USE testpy;
 
CREATE TABLE categoria
    (id iNTEGER NOT NULL PRIMARY KEY,
     nom TEXT);
 
CREATE TABLE preu
     (id iNTEGER NOT NULL PRIMARY KEY,
      url varchar(150),
      data date,
      preu REAL,
      categoria INTEGER,
      FOREIGN KEY(categoria) REFERENCES categoria(id));

Per iniciar una connexió amb MySQL o SQLite:

#connexió MySQL
nomDB = "testpy"
engine = create_engine(f"mysql+mysqlconnector://usuari:password@localhost:3306/{nomDB}")
#connexió a SQLite
nomDB = "tespy"
engine = create_engine(f'sqlite:///{nomDB }.db')

La connexió final quedarà:

Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base()
Base.metadata.create_all(engine)

Es creen els models, creem la classe Preu i Categoria

class Preu(Base):
    __tablename__ = 'preu' #nom de la taula
    id = Column(Integer, primary_key=True)  #atribut enter, clau primaria auto incremental
    url = Column(String, nullable=True) #característica string i nul
    fecha = Column(Date) 
    precio = Column(Float)
    categoria = Column(Integer, ForeignKey('categoria.id'))    
    def __init__(self, id, url, data, preu, id_cat):
        self.id = id
        self.url = url
        self.data = data
        self.preu = preu
        self.categoria = id_cat
    def donemPreu(self):
        return self.preu 
    def __str__(self):
        return f'Preu del producte:({self.id},{self.url}, {self.data}, {self.preu}, {self.categoria})'
    #atributo virtual
    @hybrid_property
    def nombreURL(self):
        return self.url
    @hybrid_method
    def major(self, quantitat):
        return self.preu > quantitat
 
 
class Categoria(Base):
    __tablename__ = 'categoria'
    id = Column(Integer, primary_key=True) 
    nombre = Column(String, nullable=True)
    def __init__(self, id, nom):
        self.id = id
        self.nom = nom
    def donemNom(self):
        return self.nom
    def __repr__(self):
        return f'Producte ({self.id},{self.nombre} )'
    def __str__(self):
        return f'Producte ({self.id},{self.nombre} )'

En aquest moment tenim creat una base de dades de MySQL, però SQLAlchemy ens permet crear la base de dades i les taules programant la creació dels models mitjançant la llibreria de sqlalchemy-utils.

També es pot aconseguir fent:

try:   
	q = "query creació DB, taula, etc"
	engine.execute(q); 
except SQLAlchemyError as e: 
	print(e)

A continuació s'aniran creant exemples amb codis de SQLAlchemy.

Per accedir a la taula farem:

ins = inspect(Categoria)
print(ins.primary_key)
print(ins.columns)

Ens permetrà aconseguir el valor de la clau primària i les columnes. Existeixen diferents atributs que mapegen característiques de la taula i el model.

Per crear una instància dins de la base de dades:

reg_categoria = Categoria(1,"informàtica")
session.add(reg_categoria)
session.commit()

Per realitzar consultes:

#obtenim l'objecte del model Preu amb la clau 0
ob = session.get(Preu,0)
print(ob)

Un exemple de com obtenir els valors mitjançant les funcions (atribut virtual)

productes = session.execute(select(Preu).where(Preu.major('100'))).scalars().all()
for producte in productes:
    print(producte, producto.donemPreu())