跳转到内容

Python 关系数据库

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

  1. 安装 Nx Console VSCode Plugin 如果您尚未安装
  2. 在VSCode中打开Nx控制台
  3. 点击 Generate (UI) 在"Common Nx Commands"部分
  4. 搜索 @aws/nx-plugin - py#rdb
  5. 填写必需参数
    • 点击 Generate
    参数类型默认值描述
    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 包导出(get_enginesession_context
      • connection.py 带 IAM 身份验证的数据库引擎和会话工厂
      • utils.py 运行时配置和本地开发助手
      • migration_handler.py 在部署期间运行 Alembic 迁移的 Lambda 处理程序
      • create_db_user_handler.py 在部署期间创建应用程序数据库用户的 Lambda 处理程序
      • 文件夹models
        • example.py 示例 SQLModel 表定义
    • 文件夹migrations
      • versions Alembic 生成的迁移脚本
      • env.py Alembic 环境(连接到数据库)
      • script.py.mako Alembic 迁移脚本模板
    • alembic.ini Alembic 配置
    • config.json 本地开发连接详细信息和运行时配置键
    • Dockerfile.migration 迁移处理程序的容器镜像
    • Dockerfile.create-db-user create-db-user 处理程序的容器镜像
    • project.json 项目配置和构建目标

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

    • 文件夹packages/common/scripts/src/rdb
      • pull-image.ts 拉取数据库容器镜像
      • start-container.ts 启动本地数据库容器
      • wait-for-postgres-db.ts 等待本地数据库就绪(PostgreSQL)
      • wait-for-mysql-db.ts 等待本地数据库就绪(MySQL)

    由于该生成器会根据您选择的 iacProvider 以基础设施即代码的形式输出,它将在 packages/common 目录下创建一个包含相关 CDK 构造体或 Terraform 模块的项目。

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

    • 文件夹packages/common/constructs
      • 文件夹src
        • 文件夹app/ 针对特定项目/生成器的基础设施构造体
        • 文件夹core/ app 目录构造体重用的通用构造体
        • index.ts 导出 app 目录构造体的入口文件
      • project.json 项目构建目标与配置
    • 文件夹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()

    数据库客户端会自动:

    • 使用 RUNTIME_CONFIG_APP_ID 环境变量从 AWS AppConfig 检索数据库配置
    • 通过 boto3 RDS Signer 为 IAM 身份验证生成临时身份验证令牌
    • 使用 ssl.create_default_context() 建立 TLS 连接

    关系型数据库生成器会根据您选择的 iacProvider 创建 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,
    }
    });
    }
    }

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

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

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

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

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

    packages/infra/src/stacks/application-stack.ts
    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,
    },
    ],
    });

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

    生成的基础设施默认包含一个 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 Root 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,
    });

    默认情况下,Performance Insights 在 Aurora 写入实例上启用(使用集群的 KMS 密钥加密)。您还可以将 Aurora 引擎日志导出到 CloudWatch LogsAurora PostgreSQL 使用 postgresqlAurora MySQL 使用 auditerrorgeneralslowquery)。为每个数据库启用日志导出:

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

    用于加密 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 Database将 Python Agent 连接到 Aurora 关系数据库
    FastAPIAmazon AuroraPython
    FastAPI to Relational Database将 FastAPI 连接到 Aurora 关系数据库
    Model Context ProtocolPythonAmazon AuroraPython
    Python MCP Server to Relational Database将 Python MCP Server 连接到 Aurora 关系数据库