Base de données relationnelle Python
Ce générateur crée un nouveau projet de base de données relationnelle Python soutenu par Amazon Aurora (PostgreSQL ou MySQL), SQLModel pour la modélisation des données, et Alembic pour les migrations de schéma. Il génère le code d’application et l’infrastructure nécessaires pour provisionner et gérer une base de données en utilisant AWS CDK ou Terraform, avec une définition de schéma déclarative, un déploiement automatique des migrations et un client de base de données.
Utilisation
Section intitulée « Utilisation »Générer une base de données relationnelle
Section intitulée « Générer une base de données relationnelle »- Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
- Ouvrez la console Nx dans VSCode
- Cliquez sur
Generate (UI)dans la section "Common Nx Commands" - Recherchez
@aws/nx-plugin - py#rdb - Remplissez les paramètres requis
- Cliquez sur
Generate
pnpm nx g @aws/nx-plugin:py#rdbyarn nx g @aws/nx-plugin:py#rdbnpx nx g @aws/nx-plugin:py#rdbbunx nx g @aws/nx-plugin:py#rdbVous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
pnpm nx g @aws/nx-plugin:py#rdb --dry-runyarn nx g @aws/nx-plugin:py#rdb --dry-runnpx nx g @aws/nx-plugin:py#rdb --dry-runbunx nx g @aws/nx-plugin:py#rdb --dry-run| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
| name Requis | string | - | Nom du projet de base de données à générer |
| directory | string | packages | Le répertoire dans lequel stocker l'application. |
| subDirectory | string | - | Le sous-répertoire dans lequel le projet est placé. Par défaut, il s'agit du nom du projet. |
| infra | aurora | none | aurora | Service de base de données relationnelle à provisionner. |
| engine | postgres | mysql | postgres | Moteur de base de données à utiliser avec le service sélectionné. |
| databaseUser | string | dbadmin | Nom d'utilisateur administrateur de la base de données. Par défaut 'dbadmin'. |
| databaseName | string | - | Nom initial de la base de données. Par défaut, le nom du projet. |
| framework | sqlmodel | sqlmodel | Framework ORM à utiliser pour le projet généré. |
| iac | inherit | cdk | terraform | inherit | Le fournisseur IaC préféré. Par défaut, il est hérité de votre sélection initiale. |
| preferInstallDependencies | boolean | true | Indique s'il faut privilégier l'installation des dépendances après l'exécution du générateur. Définir sur false pour différer l'installation lors du traitement par lots de plusieurs générateurs (une installation s'exécute toujours si nécessaire pour que les générateurs suivants puissent calculer le graphe de projet Nx) ; installer une seule fois à la fin. |
Sortie du générateur
Section intitulée « Sortie du générateur »Le générateur crée la structure de projet suivante dans le répertoire <directory>/<name> :
Répertoire<name>
- __init__.py Exports du package (
get_engine,session_context) - connection.py Moteur de base de données et fabrique de sessions avec authentification IAM
- utils.py Configuration d’exécution et assistants de développement local
- migration_handler.py Gestionnaire Lambda qui exécute les migrations Alembic pendant le déploiement
- create_db_user_handler.py Gestionnaire Lambda qui crée l’utilisateur de base de données d’application pendant le déploiement
Répertoiremodels
- example.py Exemple de définition de table SQLModel
- __init__.py Exports du package (
Répertoiremigrations
- versions Scripts de migration générés par Alembic
- env.py Environnement Alembic (se connecte à la base de données)
- script.py.mako Modèle de script de migration Alembic
- alembic.ini Configuration Alembic
- config.json Détails de connexion de développement local et clé de configuration d’exécution
- Dockerfile.migration Image de conteneur pour le gestionnaire de migration
- Dockerfile.create-db-user Image de conteneur pour le gestionnaire create-db-user
- project.json Configuration du projet et cibles de build
Les scripts de développement local sont partagés entre tous les projets de base de données et générés dans packages/common/scripts/ :
Répertoirepackages/common/scripts/src/rdb
- pull-image.ts Récupère l’image de conteneur de base de données
- start-container.ts Démarre un conteneur de base de données local
- wait-for-postgres-db.ts Attend que la base de données locale soit prête (PostgreSQL)
- wait-for-mysql-db.ts Attend que la base de données locale soit prête (MySQL)
Infrastructure
Section intitulée « Infrastructure »Ce générateur fournit de l’infrastructure as code basée sur votre iacProvider choisi. Il créera un projet dans packages/common qui inclut les constructions CDK ou modules Terraform pertinents.
Le projet commun d’infrastructure as code est structuré comme suit :
Répertoirepackages/common/constructs
Répertoiresrc
Répertoireapp/ Constructions pour l’infrastructure spécifique à un projet/générateur
- …
Répertoirecore/ Constructions génériques réutilisées par celles dans
app- …
- index.ts Point d’entrée exportant les constructions depuis
app
- project.json Cibles de build et configuration du projet
Répertoirepackages/common/terraform
Répertoiresrc
Répertoireapp/ Modules Terraform pour l’infrastructure spécifique à un projet/générateur
- …
Répertoirecore/ Modules génériques réutilisés par ceux dans
app- …
- project.json Cibles de build et configuration du projet
Répertoirepackages/common/constructs/src
Répertoireapp
Répertoiredbs
- <name>.ts Infrastructure spécifique à votre base de données
Répertoirecore
Répertoirerdb
- aurora.ts Construction générique de base de données Aurora
Répertoirepackages/common/terraform/src
Répertoireapp
Répertoiredbs
Répertoire<name>
- <name>.tf Module spécifique à votre base de données
Répertoirecore
Répertoirerdb
Répertoireaurora
- aurora.tf Module Aurora générique
Architecture
Section intitulée « Architecture »La base de données déployée a l’architecture suivante. Par défaut, un Amazon RDS Proxy se trouve devant le cluster Aurora pour mettre en commun les connexions et pour activer l’authentification IAM — voir Désactiver RDS Proxy pour l’alternative. L’architecture est la même que vous sélectionniez le moteur PostgreSQL ou MySQL ; seule la variante du moteur Aurora diffère.
Développement local
Section intitulée « Développement local »Modélisation des données
Section intitulée « Modélisation des données »Le projet généré utilise SQLModel pour définir votre schéma de base de données. Le flux de travail est axé sur le modèle : ajoutez ou mettez à jour les classes de table SQLModel dans le répertoire <name>/models/ de votre projet de base de données, puis générez une migration à partir de ces modifications de modèle.
Exemple de modèle :
from sqlalchemy import Column, Stringfrom 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))Importez vos modèles dans <name>/models/__init__.py afin qu’Alembic puisse les découvrir lors de l’autogénération.
Création de migrations
Section intitulée « Création de migrations »Après avoir ajouté ou mis à jour des modèles, utilisez Alembic pour générer et appliquer des scripts de migration. La cible alembic générée démarre automatiquement un conteneur de base de données local avant l’exécution :
pnpm nx run <project>:alembic revision --autogenerate -m "describe your change"yarn nx run <project>:alembic revision --autogenerate -m "describe your change"npx nx run <project>:alembic revision --autogenerate -m "describe your change"bunx nx run <project>:alembic revision --autogenerate -m "describe your change"Cela génère un nouveau script de migration dans migrations/versions/. Examinez le script généré avant de l’appliquer.
Appliquez la migration à votre base de données locale :
pnpm nx run <project>:migrateyarn nx run <project>:migratenpx nx run <project>:migratebunx nx run <project>:migrateLorsque vous déployez la pile AWS, l’infrastructure générée applique automatiquement les migrations générées à la base de données déployée.
Application de migrations existantes
Section intitulée « Application de migrations existantes »Lorsque vous récupérez des fichiers de migration créés par d’autres développeurs, appliquez-les à votre base de données locale :
pnpm nx run <project>:migrateyarn nx run <project>:migratenpx nx run <project>:migratebunx nx run <project>:migrateExécution de commandes Alembic
Section intitulée « Exécution de commandes Alembic »La cible alembic générée expose l’interface CLI d’Alembic, vous pouvez donc exécuter n’importe quelle commande Alembic sur la base de données locale. Consultez la référence des commandes Alembic pour les commandes disponibles.
pnpm nx run <project>:alembic <alembic-command>yarn nx run <project>:alembic <alembic-command>npx nx run <project>:alembic <alembic-command>bunx nx run <project>:alembic <alembic-command>Arrêt de la base de données locale
Section intitulée « Arrêt de la base de données locale »L’arrêt de dev (par exemple avec Ctrl+C) supprime automatiquement le conteneur de base de données local, mais préserve le volume nommé afin que vos données persistent entre les redémarrages.
Connexion à la base de données
Section intitulée « Connexion à la base de données »Importez session_context depuis votre package de base de données et utilisez-le comme gestionnaire de contexte asynchrone pour obtenir une AsyncSession :
from sqlmodel import select
from my_scope.my_db import session_contextfrom my_scope.my_db.models.example import ExampleModel
async def example(): async with session_context() as session: results = (await session.execute(select(ExampleModel))).all()Le client de base de données automatiquement :
- Récupère la configuration de la base de données depuis AWS AppConfig en utilisant la variable d’environnement
RUNTIME_CONFIG_APP_ID - Génère des jetons d’authentification temporaires via le signataire RDS
boto3pour l’authentification IAM - Établit des connexions TLS en utilisant
ssl.create_default_context()
Déploiement de votre base de données
Section intitulée « Déploiement de votre base de données »Le générateur de base de données relationnelle crée une infrastructure CDK ou Terraform en fonction de votre iacProvider sélectionné.
Le construct CDK est créé dans common/constructs. Exemple d’utilisation :
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, } }); }}Cela provisionne un cluster Aurora avec RDS Proxy, des identifiants administrateur, un utilisateur de base de données d’application, l’enregistrement de la configuration d’exécution et un gestionnaire de migration.
L’infrastructure générée crée deux utilisateurs de base de données :
- Utilisateur administrateur - Créé lors du provisionnement du cluster avec des identifiants stockés dans AWS Secrets Manager
- Utilisateur d’application - Créé via une ressource personnalisée Lambda avec l’authentification IAM activée et des privilèges DML (SELECT, INSERT, UPDATE, DELETE) sur la base de données d’application
Le module Terraform est créé dans common/terraform. Exemple d’utilisation :
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database"
vpc_id = module.vpc.vpc_id database_subnet_ids = module.vpc.private_isolated_subnet_ids lambda_subnet_ids = module.vpc.private_subnet_ids
tags = local.common_tags}Cela provisionne un cluster Aurora avec RDS Proxy, des identifiants administrateur, une Lambda create-db-user, l’enregistrement de la configuration d’exécution, une Lambda de migration et des ressources de registre de conteneurs.
L’infrastructure générée crée deux utilisateurs de base de données :
- Utilisateur administrateur - Créé lors du provisionnement du cluster avec des identifiants stockés dans AWS Secrets Manager
- Utilisateur d’application - Créé via une fonction Lambda avec l’authentification IAM activée et des privilèges DML (SELECT, INSERT, UPDATE, DELETE) sur la base de données d’application
L’utilisateur d’application est automatiquement créé avec un nom aléatoire et l’authentification IAM. Le client de base de données généré est déjà configuré pour s’authentifier en tant que cet utilisateur en utilisant des jetons RDS de courte durée, de sorte que votre code d’application ne gère jamais les mots de passe de base de données.
Votre VPC doit inclure des sous-réseaux publics, des sous-réseaux privés avec sortie et des sous-réseaux privés isolés. La base de données peut s’exécuter dans des sous-réseaux privés isolés, tandis que les fonctions Lambda d’application doivent s’exécuter dans des sous-réseaux privés avec sortie afin qu’elles puissent atteindre les services AWS tels qu’AppConfig.
const vpc = new Vpc(this, 'Vpc', { subnetConfiguration: [ { name: 'public', subnetType: SubnetType.PUBLIC, }, { name: 'private_with_egress', subnetType: SubnetType.PRIVATE_WITH_EGRESS, }, { name: 'private_isolated', subnetType: SubnetType.PRIVATE_ISOLATED, }, ],});module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 6.0"
name = "app" ... public_subnet_names = ["public"] private_subnet_names = ["private_with_egress"] intra_subnet_names = ["private_isolated"]
enable_nat_gateway = true single_nat_gateway = true}Utilisez le générateur connection pour connecter un projet à cette base de données — consultez le guide de connexion pour le type de calcul approprié (par exemple FastAPI, serveur MCP, agent) pour le câblage d’infrastructure requis pour l’atteindre.
Configuration de RDS Proxy
Section intitulée « Configuration de RDS Proxy »L’infrastructure générée inclut un RDS Proxy par défaut, qui se situe entre votre application et le cluster Aurora. RDS Proxy offre plusieurs avantages :
- Mise en commun des connexions - Maintient un pool de connexions à la base de données qui peuvent être partagées entre les instances d’application, réduisant ainsi la surcharge liée à l’établissement de nouvelles connexions
- Résilience des connexions - Gère automatiquement les basculements et les reconnexions lors des remplacements d’instances Aurora ou de la maintenance
- Authentification IAM - Prend en charge l’authentification de base de données basée sur IAM, éliminant le besoin de gérer les identifiants de base de données dans le code de votre application
- Sécurité améliorée - Applique le chiffrement TLS pour toutes les connexions
Désactiver RDS Proxy
Section intitulée « Désactiver RDS Proxy »Vous pouvez désactiver le proxy RDS comme suit :
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... enableRdsProxy: false,});Lorsque RDS Proxy est désactivé, votre application se connecte directement au point de terminaison du cluster Aurora.
Par défaut, RDS Proxy est activé. Vous pouvez le désactiver si nécessaire :
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... enable_rds_proxy = false}Lorsque RDS Proxy est désactivé, votre application se connecte directement au point de terminaison du cluster Aurora.
Exigences SSL lors de la connexion sans RDS Proxy
Section intitulée « Exigences SSL lors de la connexion sans RDS Proxy »Le bundle CA Amazon RDS doit être dans le magasin de confiance système de l’environnement d’exécution.
Environnements d’exécution de conteneur
Section intitulée « Environnements d’exécution de conteneur »ADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /etc/pki/ca-trust/source/anchors/global-bundle.pemRUN update-ca-trustADD https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem /usr/local/share/ca-certificates/rds-global-bundle.crtRUN update-ca-certificatesFonctions Lambda Zip
Section intitulée « Fonctions Lambda Zip »Pour les fonctions Lambda déployées en zip (telles qu’une py#api FastAPI), le magasin de confiance CA intégré de l’environnement d’exécution Lambda Amazon Linux 2023 inclut les CA racine Amazon utilisées par RDS.
Lors de l’utilisation de RDS Proxy, vous n’avez pas besoin de configurer le bundle CA RDS dans l’environnement d’exécution qui se connecte à la base de données.
Instances de cluster
Section intitulée « Instances de cluster »Configurez les instances d’écriture et de lecture pour votre cluster Aurora.
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... writer: ClusterInstance.serverlessV2('writer'), readers: [ClusterInstance.serverlessV2('reader')],});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... instance_count = 2 # 1 writer + 1 reader}Capacité Serverless
Section intitulée « Capacité Serverless »Contrôlez les limites de mise à l’échelle d’Aurora Serverless v2 pour correspondre à votre charge de travail.
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... serverlessV2MinCapacity: 0.5, serverlessV2MaxCapacity: 8,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... serverless_min_capacity = 0.5 serverless_max_capacity = 8}Version du moteur
Section intitulée « Version du moteur »Épinglez une version spécifique du moteur Aurora.
Par défaut, l’image de conteneur de base de données locale générée correspond à la version par défaut du moteur Aurora. Si vous modifiez la version du moteur Aurora, il est recommandé d’utiliser également une version d’image de conteneur locale correspondante pour une compatibilité maximale. Consultez les notes de version AWS pour les versions Aurora PostgreSQL et les versions Aurora MySQL pour identifier la version de base de données communautaire correspondante.
L’image de base de données locale est configurée dans le champ localDev.image du fichier config.json généré à la racine de votre projet de base de données. Mettez à jour cette valeur lorsque vous changez de version de moteur.
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... engineVersion: AuroraPostgresEngineVersion.VER_17_7,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... engine_version = "17.7"}import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... engineVersion: AuroraMysqlEngineVersion.VER_3_12_0,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... engine_version = "8.0.mysql_aurora.3.12.0"}Protection contre la suppression
Section intitulée « Protection contre la suppression »La protection contre la suppression est activée par défaut (deletionProtection: true dans CDK, deletion_protection = true dans Terraform) pour protéger le cluster Aurora contre toute suppression accidentelle.
Désactiver la protection contre la suppression
Section intitulée « Désactiver la protection contre la suppression »Vous pouvez désactiver la protection contre la suppression pour les environnements où la suppression de la base de données est attendue, comme les stacks de développement ou de prévisualisation éphémères.
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... deletionProtection: false,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... deletion_protection = false}Politique de suppression
Section intitulée « Politique de suppression »Le construct CDK conserve le cluster Aurora par défaut (removalPolicy: RemovalPolicy.RETAIN). Modifiez ceci lorsque vous souhaitez que la suppression de la stack CDK crée un snapshot ou détruise le cluster à la place.
Lors de l’utilisation de RemovalPolicy.DESTROY, la protection contre la suppression doit également être désactivée avant que le cluster puisse être supprimé.
import { RemovalPolicy } from 'aws-cdk-lib';import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... removalPolicy: RemovalPolicy.SNAPSHOT,});Pour un environnement éphémère où la base de données doit être supprimée avec la stack :
import { RemovalPolicy } from 'aws-cdk-lib';import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... deletionProtection: false, removalPolicy: RemovalPolicy.DESTROY,});Terraform n’utilise pas les politiques de suppression CDK. Par défaut, le module crée un snapshot final lors de la suppression (skip_final_snapshot = false). Pour ignorer le snapshot final pour un environnement éphémère :
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... deletion_protection = false skip_final_snapshot = true}Journalisation et surveillance
Section intitulée « Journalisation et surveillance »Performance Insights est activé par défaut sur l’instance d’écriture Aurora (chiffré avec la clé KMS du cluster). Vous pouvez également exporter les journaux du moteur Aurora vers CloudWatch Logs (postgresql pour Aurora PostgreSQL ; audit, error, general et slowquery pour Aurora MySQL). Activez l’export des journaux par base de données :
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... enableCloudwatchLogs: true, enablePerformanceInsights: false, // disable if not required});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... enable_cloudwatch_logs = true enable_performance_insights = false # disable if not required}Rotation de clé de chiffrement
Section intitulée « Rotation de clé de chiffrement »La clé KMS utilisée pour chiffrer le cluster Aurora et son secret d’identifiants a la rotation automatique des clés activée par défaut. Désactivez-la si votre politique de sécurité gère la rotation en externe.
import { MyDatabase } from ':my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { ... enableKeyRotation: false,});module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" ... enable_key_rotation = false}Connexions
Section intitulée « Connexions »Utilisez le générateur connection pour intégrer ce projet avec d’autres dans votre espace de travail. Les connexions suivantes impliquent ce projet :