Ir al contenido

Base de Datos Relacional Python

Filter this guidePick generator option values to hide sections that don't apply.

Este generador crea un nuevo proyecto de base de datos relacional Python respaldado por Amazon Aurora (PostgreSQL o MySQL), SQLModel para el modelado de datos, y Alembic para las migraciones de esquema. Genera el código de aplicación y la infraestructura necesarios para aprovisionar y administrar una base de datos usando AWS CDK o Terraform, con definición de esquema declarativa, despliegue automático de migraciones y un cliente de base de datos.

Terminal window
pnpm nx g @aws/nx-plugin:py#rdb
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
Terminal window
pnpm nx g @aws/nx-plugin:py#rdb --dry-run
ParámetroTipoPredeterminadoDescripción
name Requeridostring-Nombre del proyecto de base de datos a generar
directory stringpackagesEl directorio donde almacenar la aplicación.
subDirectory string-El subdirectorio donde se coloca el proyecto. Por defecto es el nombre del proyecto.
infra aurora | noneauroraServicio de base de datos relacional a aprovisionar.
engine postgres | mysqlpostgresMotor de base de datos a utilizar con el servicio seleccionado.
databaseUser stringdbadminNombre de usuario administrador de la base de datos. Por defecto es 'dbadmin'.
databaseName string-Nombre inicial de la base de datos. Por defecto es el nombre del proyecto.
framework sqlmodelsqlmodelFramework ORM a utilizar para el proyecto generado.
iac inherit | cdk | terraforminheritEl proveedor IaC preferido. Por defecto se hereda de tu selección inicial.
preferInstallDependencies booleantrueSi se prefiere instalar las dependencias después de que se ejecute el generador. Establecer en false para diferir la instalación al agrupar múltiples generadores (la instalación aún se ejecuta si es necesaria para que los generadores subsiguientes puedan calcular el grafo del proyecto); instalar una vez al final.

El generador crea la siguiente estructura de proyecto en el directorio <directory>/<name>:

  • Directorio<name>
    • __init__.py Package exports (get_engine, session_context)
    • connection.py Database engine and session factory with IAM authentication
    • utils.py Runtime config and local development helpers
    • migration_handler.py Lambda handler that runs Alembic migrations during deployment
    • create_db_user_handler.py Lambda handler that creates the application database user during deployment
    • Directoriomodels
      • example.py Example SQLModel table definition
  • Directoriomigrations
    • versions Alembic-generated migration scripts
    • env.py Alembic environment (connects to the database)
    • script.py.mako Alembic migration script template
  • alembic.ini Alembic configuration
  • config.json Local development connection details and runtime config key
  • Dockerfile.migration Container image for the migration handler
  • Dockerfile.create-db-user Container image for the create-db-user handler
  • project.json Project configuration and build targets

Los scripts de desarrollo local se comparten entre todos los proyectos de base de datos y se generan en packages/common/scripts/:

  • Directoriopackages/common/scripts/src/rdb
    • pull-image.ts Pulls the database container image
    • start-container.ts Starts a local database container
    • wait-for-postgres-db.ts Waits for the local database to be ready (PostgreSQL)
    • wait-for-mysql-db.ts Waits for the local database to be ready (MySQL)

Dado que este generador proporciona infraestructura como código basada en tu iac elegido, creará un proyecto en packages/common que incluye las construcciones CDK o módulos Terraform relevantes.

El proyecto común de infraestructura como código está estructurado de la siguiente manera:

  • Directoriopackages/common/constructs
    • Directoriosrc
      • Directorioapp/ Constructs for infrastructure specific to a project/generator
      • Directoriocore/ Generic constructs which are reused by constructs in app
      • index.ts Entry point exporting constructs from app
    • project.json Project build targets and configuration
  • Directoriopackages/common/constructs/src
    • Directorioapp
      • Directoriodbs
        • <name>.ts Infraestructura específica para su base de datos
    • Directoriocore
      • Directoriordb
        • aurora.ts Construcción genérica de base de datos Aurora

La base de datos desplegada tiene la siguiente arquitectura. Por defecto, un Amazon RDS Proxy se sitúa frente al clúster Aurora para agrupar conexiones y habilitar la autenticación IAM — consulta Deshabilitar RDS Proxy para la alternativa. La arquitectura es la misma ya sea que selecciones el motor PostgreSQL o MySQL; solo difiere el tipo de motor Aurora.

Application(Lambda, Agent, ...)RDS ProxyMigrations LambdaAurora(PostgreSQL or MySQL)Secrets Manager(DB credentials) SQL (IAM auth) Schema migrations Admin credentials

El proyecto generado usa SQLModel para definir tu esquema de base de datos. El flujo de trabajo es primero el modelo: agrega o actualiza clases de tabla SQLModel en el directorio <name>/models/ de tu proyecto de base de datos, luego genera una migración a partir de esos cambios de modelo.

Ejemplo de modelo:

packages/my_db/my_db/models/example.py
from sqlalchemy import Column, String
from sqlmodel import Field, SQLModel
class ExampleModel(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(sa_column=Column(String(255), nullable=False))
description: str | None = Field(default=None, sa_column=Column(String(255), nullable=True))

Importa tus modelos en <name>/models/__init__.py para que Alembic pueda descubrirlos durante la autogeneración.

Después de agregar o actualizar modelos, usa Alembic para generar y aplicar scripts de migración. El objetivo alembic generado inicia automáticamente un contenedor de base de datos local antes de ejecutarse:

Terminal window
pnpm nx run <project>:alembic revision --autogenerate -m "describe your change"

Esto genera un nuevo script de migración en migrations/versions/. Revisa el script generado antes de aplicarlo.

Aplica la migración a tu base de datos local:

Terminal window
pnpm nx run <project>:migrate

Cuando despliegues el stack de AWS, la infraestructura generada aplica automáticamente las migraciones generadas a la base de datos desplegada.

Cuando obtengas archivos de migración creados por otros desarrolladores, aplícalos a tu base de datos local:

Terminal window
pnpm nx run <project>:migrate

El objetivo alembic generado expone la CLI de Alembic, por lo que puedes ejecutar cualquier comando de Alembic contra la base de datos local. Consulta la referencia de comandos de Alembic para los comandos disponibles.

Terminal window
pnpm nx run <project>:alembic <alembic-command>

Detener dev (por ejemplo, con Ctrl+C) elimina automáticamente el contenedor de base de datos local, pero conserva el volumen nombrado para que tus datos persistan entre reinicios.

Importa session_context desde tu paquete de base de datos y úsalo como un administrador de contexto asíncrono para obtener una AsyncSession:

from sqlmodel import select
from my_scope.my_db import session_context
from my_scope.my_db.models.example import ExampleModel
async def example():
async with session_context() as session:
results = (await session.execute(select(ExampleModel))).all()

El cliente de base de datos automáticamente:

  • Recupera la configuración de la base de datos desde AWS AppConfig en tiempo de ejecución
  • Genera tokens de autenticación temporales a través de boto3 RDS Signer para autenticación IAM
  • Establece conexiones TLS usando ssl.create_default_context()

El generador de base de datos relacional crea infraestructura CDK o Terraform basada en tu iac seleccionado.

El constructo CDK se crea en common/constructs. Ejemplo de uso:

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
export class ApplicationStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
...
const db = new MyDatabase(this, 'Db', {
vpc,
vpcSubnets: {
subnetType: SubnetType.PRIVATE_ISOLATED,
}
});
}
}

Esto aprovisiona un clúster Aurora con RDS Proxy, credenciales de administrador, usuario de base de datos de aplicación, registro de configuración en tiempo de ejecución y manejador de migraciones.

La infraestructura generada crea dos usuarios de base de datos:

  • Usuario administrador - Creado durante el aprovisionamiento del clúster con credenciales almacenadas en AWS Secrets Manager
  • Usuario de aplicación - Creado a través de un recurso personalizado Lambda con autenticación IAM habilitada y privilegios DML (SELECT, INSERT, UPDATE, DELETE) en la base de datos de aplicación

El usuario de aplicación se crea automáticamente con un nombre aleatorio y autenticación IAM. El cliente de base de datos generado ya está configurado para autenticarse como este usuario usando tokens RDS de corta duración, por lo que el código de tu aplicación nunca maneja contraseñas de base de datos.

Tu VPC debe incluir subredes públicas, subredes privadas con salida y subredes privadas aisladas. La base de datos puede ejecutarse en subredes privadas aisladas, mientras que las funciones Lambda de aplicación deben ejecutarse en subredes privadas con salida para que puedan alcanzar servicios de AWS como AppConfig.

Haz clic aquí para ver una configuración de VPC de ejemplo.

Usa el generador connection para conectar un proyecto a esta base de datos — consulta la guía de conexión para el tipo de cómputo relevante (por ejemplo, FastAPI, servidor MCP, agente) para el cableado de infraestructura requerido para alcanzarla.

La imagen Docker construida para este proyecto puede ser escaneada en busca de vulnerabilidades usando Trivy, ejecutándose desde la imagen Trivy alojada en ECR.

Se agrega un target trivy a tu proyecto que escanea la imagen construida y termina con código distinto de cero si se encuentra alguna vulnerabilidad de severidad HIGH o CRITICAL. El Dockerfile generado usa una imagen base sin vulnerabilidades corregibles conocidas de estas severidades al momento de la generación, y actualiza las herramientas incluidas (como npm) para mantenerlo así.

El escaneo usa el mismo motor de contenedores que tu construcción de imagen (docker o finch), por lo que no se requieren herramientas adicionales. Dado que el escaneo solo se vuelve a ejecutar cuando la imagen cambia, una imagen sin cambios no se vuelve a escanear. El script raíz trivy proporcionado escanea cada imagen en el workspace:

Terminal window
pnpm trivy

Puede haber instancias en las que desees suprimir una vulnerabilidad específica, por ejemplo cuando aún no hay una corrección disponible y has evaluado el riesgo como aceptable.

Agrega el ID de vulnerabilidad (uno por línea) al archivo .trivyignore en la raíz de tu proyecto (es decir, junto a tu project.json):

.trivyignore
# node-tar arbitrary file write - not exploitable in our usage
CVE-2024-XXXXX

Para más detalles sobre el filtrado de hallazgos, consulta la documentación de filtrado de Trivy.

La infraestructura generada incluye un RDS Proxy de forma predeterminada, que se sitúa entre tu aplicación y el clúster Aurora. RDS Proxy proporciona varios beneficios:

  • Agrupación de conexiones - Mantiene un pool de conexiones de base de datos que pueden compartirse entre instancias de aplicación, reduciendo la sobrecarga de establecer nuevas conexiones
  • Resiliencia de conexión - Maneja automáticamente las conmutaciones por error y reconexiones durante reemplazos de instancias Aurora o mantenimiento
  • Autenticación IAM - Admite autenticación de base de datos basada en IAM, eliminando la necesidad de gestionar credenciales de base de datos en el código de tu aplicación
  • Seguridad mejorada - Aplica cifrado TLS para todas las conexiones

Puedes deshabilitar el proxy RDS de la siguiente manera:

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
enableRdsProxy: false,
});

Cuando RDS Proxy está deshabilitado, tu aplicación se conecta directamente al endpoint del clúster Aurora.

El paquete de CA de Amazon RDS debe estar en el almacén de confianza del sistema del tiempo de ejecución.

ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /etc/pki/ca-trust/source/anchors/global-bundle.pem
RUN update-ca-trust

Para funciones Lambda desplegadas como zip (como una py#api FastAPI), el almacén de confianza de CA integrado del entorno de ejecución Lambda de Amazon Linux 2023 incluye las CA raíz de Amazon utilizadas por RDS.

Cuando uses RDS Proxy, no necesitas configurar el paquete de CA de RDS en el tiempo de ejecución que se conecta a la base de datos.

Configure las instancias de escritura y lectura para su clúster Aurora.

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
writer: ClusterInstance.serverlessV2('writer'),
readers: [ClusterInstance.serverlessV2('reader')],
});

Controla los límites de escalado de Aurora Serverless v2 para que coincidan con tu carga de trabajo.

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
serverlessV2MinCapacity: 0.5,
serverlessV2MaxCapacity: 8,
});

Fija una versión específica del motor Aurora.

Por defecto, la imagen del contenedor de la base de datos local generada coincide con la versión predeterminada del motor Aurora. Si cambias la versión del motor Aurora, se recomienda también usar una versión de imagen de contenedor local que coincida para máxima compatibilidad. Consulta las notas de lanzamiento de AWS para versiones de Aurora PostgreSQL y versiones de Aurora MySQL para identificar la versión correspondiente de la base de datos comunitaria.

La imagen de la base de datos local se configura en el campo localDev.image del archivo config.json generado en la raíz de tu proyecto de base de datos. Actualiza ese valor cuando cambies las versiones del motor.

engine = postgres
packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
engineVersion: AuroraPostgresEngineVersion.VER_17_7,
});
engine = mysql
packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
engineVersion: AuroraMysqlEngineVersion.VER_3_12_0,
});

La protección contra eliminación está habilitada por defecto (deletionProtection: true en CDK, deletion_protection = true en Terraform) para proteger el clúster Aurora de eliminaciones accidentales.

Deshabilitar la Protección contra Eliminación

Sección titulada «Deshabilitar la Protección contra Eliminación»

Puede deshabilitar la protección contra eliminación para entornos donde se espera la eliminación de la base de datos, como stacks de desarrollo o vista previa de corta duración.

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
deletionProtection: false,
});

El constructo CDK retiene el clúster Aurora por defecto (removalPolicy: RemovalPolicy.RETAIN). Cambia esto cuando quieras que la eliminación del stack CDK haga una instantánea o destruya el clúster en su lugar.

Cuando uses RemovalPolicy.DESTROY, la protección contra eliminación también debe estar deshabilitada antes de que el clúster pueda ser eliminado.

packages/infra/src/stacks/application-stack.ts
import { RemovalPolicy } from 'aws-cdk-lib';
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
removalPolicy: RemovalPolicy.SNAPSHOT,
});

Para un entorno efímero donde la base de datos debe ser eliminada con el stack:

packages/infra/src/stacks/application-stack.ts
import { RemovalPolicy } from 'aws-cdk-lib';
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
deletionProtection: false,
removalPolicy: RemovalPolicy.DESTROY,
});
engine = postgres

El registro postgresql se exporta para Aurora PostgreSQL, con el registro limitado solo a declaraciones DDL (log_statement=ddl) para que los valores de los parámetros de las declaraciones nunca se registren, siempre y cuando cada declaración se envíe por separado. log_statement=ddl registra todo el texto sin procesar de un lote de múltiples declaraciones (por ejemplo, una sola llamada psql -c "a;b;c") de forma literal si alguna declaración en él es DDL, incluyendo cualquier valor DML en ese mismo lote.

engine = mysql

Los registros audit y error se exportan para Aurora MySQLgeneral y slowquery se excluyen deliberadamente ya que registran el texto completo de las sentencias, incluidos los valores DML. Advanced Auditing está limitado a conexiones y DDL (server_audit_events=CONNECT,QUERY_DDL), por lo que los valores de los parámetros de las sentencias nunca se registran.

Performance Insights está habilitado en la instancia de escritura de Aurora de forma predeterminada (cifrado con la clave KMS del clúster). Los registros del motor de Aurora también se exportan a CloudWatch Logs de forma predeterminada, configurados para mostrar actividad a nivel de esquema sin filtrar datos de filas.

Deshabilite la exportación de registros por base de datos si no es necesario:

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
enableCloudwatchLogs: false,
enablePerformanceInsights: false,
});

La clave KMS utilizada para cifrar el clúster Aurora y su secreto de credenciales tiene la rotación automática de claves habilitada por defecto. Deshabilítela si su política de seguridad gestiona la rotación externamente.

packages/infra/src/stacks/application-stack.ts
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', {
...
enableKeyRotation: false,
});

Usa el generador connection para integrar este proyecto con otros en tu espacio de trabajo. Las siguientes conexiones involucran este proyecto:

Strands AgentsPythonAmazon AuroraPython
Python Agent to Relational DatabaseConnect a Python Agent to an Aurora relational database
FastAPIAmazon AuroraPython
FastAPI to Relational DatabaseConnect a FastAPI to an Aurora relational database
Model Context ProtocolPythonAmazon AuroraPython
Python MCP Server to Relational DatabaseConnect a Python MCP Server to an Aurora relational database