SQLAlchemy es un kit de herramientas SQL de código abierto y un mapeador relacional de objetos (ORM) para el lenguaje de programación Python publicado bajo la licencia MIT . [5]
La filosofía de SQLAlchemy es que las bases de datos relacionales se comportan menos como colecciones de objetos a medida que la escala aumenta y el rendimiento comienza a ser una preocupación, mientras que las colecciones de objetos se comportan menos como tablas y filas a medida que se diseña más abstracción en ellas. Por esta razón, ha adoptado el patrón de mapeo de datos (similar a Hibernate para Java ) en lugar del patrón de registro activo utilizado por otros mapeadores relacionales de objetos. [6]
SQLAlchemy se lanzó por primera vez en febrero de 2006. [3] SQLAlchemy beta 2.0 se lanzó en octubre de 2022 y la versión 2.0 completa a principios de 2023. [7] [8]
El siguiente ejemplo representa una relación n a 1 entre películas y sus directores. Se muestra cómo las clases de Python definidas por el usuario crean tablas de bases de datos correspondientes, cómo se crean instancias con relaciones desde ambos lados de la relación y, finalmente, cómo se pueden consultar los datos, lo que ilustra consultas SQL generadas automáticamente para cargas diferidas y ansiosas.
Crear dos clases de Python y las tablas de bases de datos correspondientes en el DBMS:
desde sqlalchemy import * desde sqlalchemy.ext.declarative import declarative_base desde sqlalchemy.orm import relación , sessionmakerBase = base_declarativa ()clase Película ( Base ): __tablename__ = "películas" id = Columna ( Entero , clave_primaria = Verdadero ) título = Columna ( Cadena ( 255 ), anulable = Falso ) año = Columna ( Entero ) dirigida_por = Columna ( Entero , ForeignKey ( "directors.id" )) director = relación ( "Director" , backref = "películas" , lazy = False ) def __init__ ( self , título = Ninguno , año = Ninguno ): self . título = título propio . año = año def __repr__ ( self ): devuelve "Película( %r , %r , %r )" % ( self . título , self . año , self . director ) Director de clase ( Base ): __tablename__ = "directores" id = Columna ( Entero , clave_primaria = Verdadero ) nombre = Columna ( Cadena ( 50 ), anulable = Falso , único = Verdadero ) def __init__ ( self , nombre = Ninguno ): self . nombre = nombre def __repr__ ( self ): devuelve "Director( %r )" % ( self . nombre )motor = create_engine ( "dbms://usuario:pwd@host/dbname" ) Base . metadatos . create_all ( motor )
Se puede insertar una relación director-película a través de cualquiera de las entidades:
Sesión = creador de sesiones ( enlace = motor ) sesión = Sesión ()m1 = Película ( "Robocop" , 1987 ) m1 . director = Director ( "Paul Verhoeven" )d2 = Director ( "George Lucas" ) d2 . películas = [ Película ( "Star Wars" , 1977 ), Película ( "THX 1138" , 1971 )]prueba : sesión . añadir ( m1 ) sesión . añadir sesión ( d2 ) . confirmar () excepto : sesión . Retroceder ()
todos los datos = sesión . consulta ( Película ) . all () para algunos datos en todos los datos : imprimir ( algunos datos )
SQLAlchemy emite la siguiente consulta al DBMS (omitiendo alias):
SELECCIONAR películas . identificación , películas . título , películas . año , películas . dirigido_por , directores . identificación , directores . nombre DE películas IZQUIERDA EXTERIOR UNIR directores EN directores . identificación = películas . dirigido por
La salida:
Película ( 'Robocop' , 1987 L , Director ( 'Paul Verhoeven' )) Película ( 'Star Wars' , 1977 L , Director ( 'George Lucas' )) Película ( 'THX 1138' , 1971 L , Director ( 'George Lucas ' ))
En su lugar, configurando lazy=True
(predeterminado), SQLAlchemy primero emitiría una consulta para obtener la lista de películas y solo cuando fuera necesario (vago) para cada director una consulta para obtener el nombre del director correspondiente:
SELECCIONAR películas . identificación , películas . título , películas . año , películas . dirigido_por DE películas SELECCIONAR directores . identificación , directores . nombre DE directores DONDE directores . identificación = % s