跳转到内容

Python 关系数据库

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

此生成器创建一个新的 Python 关系数据库项目,由 Amazon Aurora(PostgreSQL 或 MySQL)、SQLModel 用于数据建模,以及 Alembic 用于模式迁移提供支持。它生成应用程序代码和基础设施,使用 AWS CDK 或 Terraform 来配置和管理数据库,具有声明式模式定义、自动迁移部署和数据库客户端。

Terminal window
pnpm nx g @aws/nx-plugin:py#rdb
您还可以执行试运行以查看哪些文件会被更改
Terminal window
pnpm nx g @aws/nx-plugin:py#rdb --dry-run
参数类型默认值描述
name 必需string-要生成的数据库项目名称
directory stringpackages存储应用程序的目录。
subDirectory string-项目所在的子目录。默认为项目名称。
infra aurora | noneaurora要配置的关系数据库服务。
engine postgres | mysqlpostgres与所选服务一起使用的数据库引擎。
databaseUser stringdbadmin数据库管理员用户名。默认为 'dbadmin'。
databaseName string-初始数据库名称。默认为项目名称。
framework sqlmodelsqlmodel用于生成项目的 ORM 框架。
iac inherit | cdk | terraforminherit首选的 IaC 提供商。默认情况下,这继承自您的初始选择。
preferInstallDependencies booleantrue是否在生成器运行后优先安装依赖项。设置为 false 可在批量运行多个生成器时延迟安装(如果后续生成器需要计算 Nx 项目图,仍会运行安装);最后统一安装一次。

生成器在 <directory>/<name> 目录中创建以下项目结构:

  • 文件夹<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
    • 文件夹models
      • example.py Example SQLModel table definition
  • 文件夹migrations
    • 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

本地开发脚本在所有数据库项目之间共享,并生成到 packages/common/scripts/

  • 文件夹packages/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)

由于此生成器根据您选择的 iac 提供基础设施即代码,它将在 packages/common 中创建一个项目,其中包含相关的 CDK 构造或 Terraform 模块。

通用基础设施即代码项目的结构如下:

  • 文件夹packages/common/constructs
    • 文件夹src
      • 文件夹app/ Constructs for infrastructure specific to a project/generator
      • 文件夹core/ Generic constructs which are reused by constructs in app
      • index.ts Entry point exporting constructs from app
    • project.json Project build targets and configuration
  • 文件夹packages/common/constructs/src
    • 文件夹app
      • 文件夹dbs
        • <name>.ts 特定于您的数据库的基础设施
    • 文件夹core
      • 文件夹rdb
        • aurora.ts 通用 Aurora 数据库构造

已部署的数据库具有以下架构。默认情况下,Amazon RDS Proxy 位于 Aurora 集群前面以池化连接并启用 IAM 身份验证 — 有关替代方案,请参阅禁用 RDS Proxy。无论您选择 PostgreSQL 还是 MySQL 引擎,架构都是相同的;只有 Aurora 引擎类型不同。

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

生成的项目使用 SQLModel 来定义您的数据库模式。工作流程是模型优先的:在数据库项目的 <name>/models/ 目录下添加或更新 SQLModel 表类,然后从这些模型更改生成迁移。

示例模型:

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))

<name>/models/__init__.py 中导入您的模型,以便 Alembic 在自动生成期间可以发现它们。

在添加或更新模型后,使用 Alembic 生成并应用迁移脚本。生成的 alembic 目标在运行之前会自动启动本地数据库容器:

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

这会在 migrations/versions/ 下生成一个新的迁移脚本。在应用之前请检查生成的脚本。

将迁移应用到您的本地数据库:

Terminal window
pnpm nx run <project>:migrate

当您部署 AWS 堆栈时,生成的基础设施会自动将生成的迁移应用到已部署的数据库。

当您拉取其他开发人员创建的迁移文件时,将它们应用到您的本地数据库:

Terminal window
pnpm nx run <project>:migrate

生成的 alembic 目标公开了 Alembic CLI,因此您可以对本地数据库运行任何 Alembic 命令。有关可用命令,请参阅 Alembic 命令参考

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

停止 dev(例如使用 Ctrl+C)会自动删除本地数据库容器,但会保留命名卷,以便您的数据在重启后保持不变。

从您的数据库包中导入 session_context 并将其用作异步上下文管理器以获取 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()

数据库客户端会自动:

  • 在运行时从 AWS AppConfig 检索数据库配置
  • 通过 boto3 RDS Signer 生成临时身份验证令牌以进行 IAM 身份验证
  • 使用 ssl.create_default_context() 建立 TLS 连接

关系数据库生成器会根据您选择的 iac 创建 CDK 或 Terraform 基础设施。

CDK 构造在 common/constructs 中创建。使用示例:

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,
}
});
}
}

这将配置一个带有 RDS Proxy、管理员凭证、应用程序数据库用户、运行时配置注册和迁移处理程序的 Aurora 集群。

生成的基础设施会创建两个数据库用户:

  • 管理员用户 - 在集群配置期间创建,凭证存储在 AWS Secrets Manager 中
  • 应用程序用户 - 通过 Lambda 自定义资源创建,启用 IAM 身份验证,并在应用程序数据库上具有 DML 权限(SELECT、INSERT、UPDATE、DELETE)

应用程序用户会自动创建,具有随机名称和 IAM 身份验证。生成的数据库客户端已配置为使用短期 RDS 令牌以此用户身份进行身份验证,因此您的应用程序代码永远不会处理数据库密码。

您的 VPC 应包括公有子网、具有出口的私有子网和私有隔离子网。数据库可以在私有隔离子网中运行,而应用程序 Lambda 函数应在具有出口的私有子网中运行,以便它们可以访问 AWS 服务(如 AppConfig)。

点击此处查看 VPC 配置示例。

使用 connection 生成器将项目连接到此数据库 — 请参阅相关计算类型(例如 FastAPI、MCP 服务器、代理)的连接指南,了解访问数据库所需的基础设施配置。

为此项目构建的 Docker 镜像可以使用 Trivy 进行漏洞扫描,该工具从 ECR 托管的 Trivy 镜像运行。

项目中会添加一个 trivy 目标,用于扫描构建的镜像,如果发现任何 HIGHCRITICAL 严重级别的漏洞,将以非零状态退出。生成的 Dockerfile 使用的基础镜像在生成时没有已知的可修复漏洞(这些严重级别),并升级捆绑的工具(如 npm)以保持这种状态。

扫描使用与镜像构建相同的容器引擎(dockerfinch),因此不需要额外的工具。由于扫描仅在镜像更改时重新运行,未更改的镜像不会被重新扫描。提供的 trivy 根脚本会扫描工作区中的每个镜像:

Terminal window
pnpm trivy

在某些情况下,您可能希望抑制特定的漏洞,例如当尚无可用修复且您已评估风险为可接受时。

将漏洞 ID(每行一个)添加到项目根目录中的 .trivyignore 文件(即 project.json 旁边):

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

有关过滤发现的更多详细信息,请参阅 Trivy 过滤文档

生成的基础设施默认包含一个 RDS Proxy,它位于您的应用程序和 Aurora 集群之间。RDS Proxy 提供了几个好处:

  • 连接池 - 维护一个可以在应用程序实例之间共享的数据库连接池,减少建立新连接的开销
  • 连接弹性 - 在 Aurora 实例替换或维护期间自动处理故障转移和重新连接
  • IAM 身份验证 - 支持基于 IAM 的数据库身份验证,无需在应用程序代码中管理数据库凭证
  • 改进的安全性 - 对所有连接强制执行 TLS 加密

您可以按如下方式禁用 RDS 代理:

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

当 RDS Proxy 被禁用时,您的应用程序将直接连接到 Aurora 集群端点。

不使用 RDS Proxy 连接时的 SSL 要求

Section titled “不使用 RDS Proxy 连接时的 SSL 要求”

Amazon RDS CA 捆绑包必须位于运行时的系统信任存储中。

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

对于 zip 部署的 Lambda 函数(例如 py#api FastAPI),Amazon Linux 2023 Lambda 执行环境的内置 CA 信任存储包含 RDS 使用的 Amazon 根 CA。

使用 RDS Proxy 时,您无需在连接到数据库的运行时中配置 RDS CA 捆绑包。

为您的 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')],
});

控制 Aurora Serverless v2 扩展限制以匹配您的工作负载。

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,
});

固定特定的 Aurora 引擎版本。

默认情况下,生成的本地数据库容器镜像与默认的 Aurora 引擎版本匹配。如果您更改 Aurora 引擎版本,建议同时使用匹配的本地容器镜像版本以获得最大兼容性。请参阅 AWS 发布说明中的 Aurora PostgreSQL 版本Aurora MySQL 版本 以确定相应的社区数据库版本。

本地数据库镜像在数据库项目根目录中生成的 config.json 文件的 localDev.image 字段中配置。当您更改引擎版本时,请更新该值。

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,
});

默认情况下启用删除保护(CDK 中为 deletionProtection: true,Terraform 中为 deletion_protection = true),以保护 Aurora 集群免遭意外删除。

您可以为预期会删除数据库的环境禁用删除保护,例如短期开发或预览堆栈。

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

CDK 构造默认保留 Aurora 集群(removalPolicy: RemovalPolicy.RETAIN)。当您希望 CDK 堆栈删除时改为快照或销毁集群时,请更改此设置。

使用 RemovalPolicy.DESTROY 时,还必须禁用删除保护才能删除集群。

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,
});

对于应随堆栈一起删除数据库的临时环境:

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

postgresql 日志会导出到 Aurora PostgreSQL,日志记录范围仅限于 DDL 语句(log_statement=ddl),因此永远不会记录语句参数值——只要每个语句单独发送。log_statement=ddl 会逐字记录多语句批处理的整个原始文本(例如单个 psql -c "a;b;c" 调用),如果其中任何语句是 DDL,则包括同一批处理中的任何 DML 值。

engine = mysql

对于 Aurora MySQL,会导出 auditerror 日志——故意排除了 generalslowquery,因为它们会记录完整的语句文本,包括 DML 值。高级审计的范围限定为连接和 DDL(server_audit_events=CONNECT,QUERY_DDL),因此永远不会记录语句参数值。

Performance Insights 默认在 Aurora 写入器实例上启用(使用集群的 KMS 密钥加密)。Aurora 引擎日志也默认导出到 CloudWatch Logs,配置为显示架构级活动而不泄露行数据。

如果不需要,可以按数据库禁用日志导出:

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

用于加密 Aurora 集群及其凭证密钥的 KMS 密钥默认启用自动密钥轮换。如果您的安全策略在外部管理轮换,请禁用它。

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

使用 connection 生成器将此项目与工作空间中的其他项目集成。以下连接涉及此项目:

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