En este artículo vamos a ver cómo describir Bases de Datos con MetaData usando SQLAlchemy en Python.
Los metadatos de la base de datos describen la estructura de la base de datos en términos de estructuras de datos de Python. La base de datos generalmente consta de tablas y columnas. Los metadatos de la base de datos nos sirven para generar consultas SQL y mapeo relacional de objetos. Nos ayuda a generar un Esquema. Los objetos más fundamentales de los metadatos de la base de datos son los metadatos, la tabla y la columna.
Describiendo bases de datos con metadatos: SQLAlchemy Core
Configuración de metadatos con objetos de tabla:
Las consultas en una base de datos relacional generalmente se crean en una tabla de una base de datos. Estas tablas se representan como objetos de tabla en Python SQLAlchemy con el nombre de tabla. Los metadatos son un objeto que consta de objetos de tabla codificados con sus nombres de string. La sintaxis para crear un objeto MetaData es la siguiente:
from sqlalchemy import MetaData metadata_obj=MetaData()
Un solo objeto MetaData es suficiente para una aplicación completa. Una vez que se crea el objeto MetaData, podemos declarar objetos Table. Veamos un ejemplo de creación de una tabla para una cuenta de estudiante que consta de columnas: nombre, edad y grado y también agregamos una identificación como clave principal.
Ahora convertimos la tabla anterior en un Esquema usando el objeto MetaData.
Python3
from sqlalchemy import MetaData from sqlalchemy import Integer, String, Column, Table metadata_object=MetaData() student_table = Table( "student_account", metadata_object, Column('id', Integer, primary_key=True), Column('name', String(30)), Column('age',Integer), Column('grade', String(80)) )
En el código anterior, una tabla representa una tabla de base de datos que se asigna a sí misma al objeto MetaData.
Una Columna representa una Columna de una Tabla que se asigna a sí misma al objeto Tabla. La columna generalmente contiene un nombre de string y un objeto de tipo como Integer, String, etc.
Crear una tabla con diferentes tipos de datos
Python3
from sqlalchemy import create_engine from sqlalchemy import DateTime, Numeric, Enum item_detail = Table( "items", metadata_object, Column("key", String(50), primary_key=True), Column("timestamp", DateTime), Column("price", Numeric(100, 2)), Column("type", Enum("dry", "wet")), ) # creating an engine object engine = create_engine("sqlite+pysqlite:///:memory:", echo=True, future=True) # emitting DDL metadata_object.create_all(engine)
Acceso a tablas y columnas
Las columnas de una tabla generalmente se almacenan en una array asociativa, es decir, Table.c , y se puede acceder a ellas usando «c», como se muestra en los siguientes ejemplos.
Obteniendo el nombre de la tabla:
Python3
student_table.name
Producción:
'student_account'
Accediendo a columnas usando el operador c:
Python3
student_table.c.name
Producción:
Columna(‘nombre’, String(longitud=30), tabla=<cuenta_del_estudiante>)
Acceso al nombre de una columna (nombre):
Python3
student_table.c.name.name
Producción:
name
Tipo de acceso de una columna:
Python3
student_table.c.name.type
Producción:
String(length=30)
Obtener la clave principal de una tabla:
Python3
student_table.primary_key
Producción:
PrimaryKeyConstraint(Column(‘id’, Integer(), table=<student_account>, primary_key=True, anulable=False))
Acceder a tablas y claves usando el objeto MetaData
El objeto de metadatos se puede utilizar para acceder a todas las tablas almacenadas en el objeto de metadatos, como se muestra en los siguientes ejemplos:
Acceso a tablas en metadatos:
Python3
metadata_object.tables
Producción:
FacadeDict({‘cuenta_estudiante’: Table(‘cuenta_estudiante’, MetaData(), Column(‘id’, Integer(), table=<cuenta_estudiante>, clave_principal=Verdadero, anulable=Falso), Columna(‘nombre’, String( length=30), table=<cuenta_estudiante>), Column(‘edad’, Integer(), table=<cuenta_estudiante>), Column(‘calificación’, String(longitud=80), table=<cuenta_estudiante>), esquema =Ninguno), ‘elementos’: Tabla(‘elementos’, MetaData(), Columna(‘clave’, String(longitud=50), tabla=<elementos>, clave_principal=Verdadero, anulable=Falso), Columna(‘marca de tiempo ‘, DateTime(), table=<items>), Column(‘price’, Numeric(precision=100, scale=2), table=<items>), Column(‘type’, Enum(‘dry’, ‘ húmedo’), tabla=<elementos>), esquema=Ninguno)})
Acceso a claves de tablas:
Python3
metadata_object.tables.keys()
Producción:
dict_keys(['student_account', 'items'])
Declaración de restricciones
Como puede ver, hemos declarado la primera columna como clave principal en la tabla_estudiante. Ejecutar el siguiente comando mostrará los detalles de la restricción de clave principal.
Python3
student_table.primary_key
Producción:
PrimaryKeyConstraint(Column(‘id’, Integer(), table=<student_account>, primary_key=True, anulable=False))
Una restricción de clave principal normalmente se declara implícitamente, mientras que una ForeignKeyConstraint se declara explícitamente. Usamos restricciones de clave externa si dos tablas están relacionadas entre sí mediante el objeto ForeignKey.
Vamos a crear una nueva tabla llamada address_table que consta de la dirección de correo electrónico del estudiante y tendremos una restricción de clave externa que se refiere a la tabla de estudiantes.
Python3
from sqlalchemy import ForeignKey address_table = Table( "address", metadata_object, Column('id', Integer, primary_key=True), Column('student_id', ForeignKey('student_account.id'), nullable=False), Column('email_address', String, nullable=False) )
Creación y eliminación de tablas
Crear tabla:
Hasta ahora hemos creado dos Tablas con un conjunto de Columnas y restricciones. Lo siguiente es que tenemos que emitir DDL a la base de datos SQLite (en este caso) para que podamos consultar con las tablas. Esto se puede hacer como se muestra a continuación:
Python3
from sqlalchemy import create_engine # creating an engine object engine = create_engine("sqlite+pysqlite:///:memory:", echo=True, future=True) # emitting DDL metadata_object.create_all(engine)
Producción:
Mesa de caída
El método drop_all() se utiliza para eliminar todas las tablas en el objeto de metadatos.
Python
from sqlalchemy import create_engine # creating an engine object engine = create_engine("sqlite+pysqlite:///:memory:", echo=True, future=True) # emitting DDL metadata_object.drop_all(engine)
Producción:
Describiendo bases de datos con metadatos: SQLAlchemy ORM
Aprenderemos a crear las mismas tablas que hemos creado usando Core con ORM. El ORM consta de clases mapeadas. Las clases asignadas se declaran de la misma manera que se crea cualquier clase de Python y vinculamos los atributos de las clases asignadas a las columnas de la tabla.
En ORM, el objeto MetaData se combina con el objeto ORM-Only llamado Registro. Construimos el Registro como se muestra a continuación:
Python3
from sqlalchemy.orm import registry mapper_registry = registry() mapper_registry.metadata
Producción:
MetaData()
En ORM, en lugar de declarar los objetos Table directamente, los declaramos indirectamente mediante el uso de clases asignadas. Las clases mapeadas descienden de un directorio base conocido como Base Declarativa. La base declarativa se puede crear usando el registro usando el método registration.generate_base().
Python3
Base = mapper_registry.generate_base()
Esta clase base sirve como clase base para las clases mapeadas de ORM que declaramos. Las dos tablas Student_account y address se pueden crear usando ORM como se muestra a continuación.
Python3
from sqlalchemy.orm import relationship class Student(Base): __tablename__ = 'student_account' id = Column(Integer, primary_key=True) name = Column(String(30)) age = Column(Integer) grade = Column(String) addresses = relationship("Address", back_populates="student") def __repr__(self): return f"Student(id={self.id!r}, name={self.name!r},\ age={self.age!r},grade={self.grade!r})" class Address(Base): __tablename__ = 'address' id = Column(Integer, primary_key=True) email_address = Column(String, nullable=False) student_id = Column(Integer, ForeignKey('student_account.id')) student = relationship("Student", back_populates="addresses") def __repr__(self): return f"Address(id={self.id!r}, email_address={self.email_address!r})"
El atributo .__table__ se usa para ver los objetos Table creados a partir de clases mapeadas declarativas, como se muestra a continuación:
Python3
Student.__table__
Producción:
Table('student_account', MetaData(), Column('id', Integer(), table=<student_account>, primary_key=True, nullable=False), Column('name', String(length=30), table=<student_account>), Column('age', Integer(), table=<student_account>), Column('grade', String(), table=<student_account>), schema=None)
Python3
Address.__table__
Producción:
Table('address', MetaData(), Column('id', Integer(), table=<address>, primary_key=True, nullable=False), Column('email_address', String(), table=<address>, nullable=False), Column('student_id', Integer(), ForeignKey('student_account.id'), table=<address>), schema=None)
Emitiendo DDL:
En ORM, para emitir DDL usamos el objeto MetaData asociado con nuestro registro y la clase base declarativa ORM.
Python3
mapper_registry.metadata.create_all(engine) Base.metadata.create_all(engine)
Producción:
Reflexión de la mesa
«Reflexión» se refiere a la carga de objetos de la tabla en función de la lectura de una tabla existente. Por ejemplo, crearemos un nuevo objeto Table que representa el objeto student_account que creamos manualmente en las secciones anteriores de este artículo como se muestra a continuación.
Python3
metadata2=MetaData() with engine.connect() as conn: student_reflected=Table("student_account", metadata2, autoload_with=conn)
Producción:
Ahora puede acceder a las columnas de la tabla reflejada que acabamos de crear de la siguiente manera:
Python3
print(student_reflected.c) print(student_reflected.primary_key)
Producción:
ImmutableColumnCollection(cuenta_estudiante.id, cuenta_estudiante.nombre, cuenta_estudiante.edad, cuenta_estudiante.grado)
PrimaryKeyConstraint(Column(‘id’, INTEGER(), table=<student_account>, primary_key=True, anulable=False))
Publicación traducida automáticamente
Artículo escrito por namaldesign y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA