FastAPI đến Cơ sở dữ liệu Quan hệ
Generator connection kết nối một FastAPI với dự án Python Relational Database, tiêm một session SQLModel có kiểu vào các route handler của bạn thông qua một dependency của FastAPI.
Điều kiện tiên quyết
Phần tiêu đề “Điều kiện tiên quyết”Trước khi sử dụng generator này, hãy đảm bảo bạn có:
Cách sử dụng
Phần tiêu đề “Cách sử dụng”Chạy Generator
Phần tiêu đề “Chạy Generator”Chạy generator này@aws/nx-plugin:connection
pnpm nx g @aws/nx-plugin:connection yarn nx g @aws/nx-plugin:connection npx nx g @aws/nx-plugin:connection bunx nx g @aws/nx-plugin:connection- Cài đặt Nx Console VSCode Plugin nếu bạn chưa cài đặt
- Mở Nx Console trong VSCode
- Nhấp
Generate (UI)trong phần "Common Nx Commands" - Tìm kiếm
@aws/nx-plugin - connection - Điền các tham số bắt buộc
- Nhấp
Generate
Xây dựng lệnh của bạn5
Bắt buộc
Bắt buộc
Chọn dự án FastAPI của bạn làm nguồn và dự án cơ sở dữ liệu quan hệ của bạn làm đích.
Tùy chọn
Phần tiêu đề “Tùy chọn”sourceProjectBắt buộcstringDự án nguồn
targetProjectBắt buộcstringDự án đích để kết nối tới
sourceComponentstringComponent nguồn để kết nối từ đó (tên component, đường dẫn tương đối so với thư mục gốc của dự án nguồn, hoặc id của generator). Sử dụng '.' để chọn rõ ràng dự án làm nguồn.
targetComponentstringComponent đích để kết nối tới (tên component, đường dẫn tương đối so với thư mục gốc của dự án đích, hoặc id của generator). Sử dụng '.' để chọn rõ ràng dự án làm đích.
preferInstallDependenciesbooleanMặc định:trueCó nên cài đặt các dependencies sau khi generator chạy hay không. Đặt thành false để trì hoãn việc cài đặt khi chạy nhiều generator liên tiếp (việc cài đặt vẫn sẽ chạy nếu cần thiết để các generator tiếp theo có thể tính toán Nx project graph); cài đặt một lần vào cuối.
Kết quả của Generator
Phần tiêu đề “Kết quả của Generator”Generator sửa đổi dự án FastAPI của bạn:
Thư mụcpackages/my_api
- project.json Thêm một dependency từ
devvào targetdevcủa cơ sở dữ liệu - pyproject.toml Thêm package cơ sở dữ liệu như một workspace dependency
Thư mụcmy_api
Thư mụcdependencies
- my_db.py Dependency
MyDbSessioncủa FastAPI cho database session
- my_db.py Dependency
- project.json Thêm một dependency từ
Sử dụng Cơ sở dữ liệu trong Route Handler
Phần tiêu đề “Sử dụng Cơ sở dữ liệu trong Route Handler”Generator này cấu hình một FastAPI Dependency có thể tiêm mà bạn có thể sử dụng trong các route handler của mình:
from sqlmodel import selectfrom my_api.dependencies.my_db import MyDbSessionfrom my_scope_my_db.models.example import ExampleModel
@app.get("/examples")async def list_examples(my_db: MyDbSession): return (await my_db.execute(select(ExampleModel))).scalars().all()
@app.post("/examples")async def create_example(name: str, my_db: MyDbSession): item = ExampleModel(name=name) my_db.add(item) await my_db.commit() await my_db.refresh(item) return itemFastAPI tự động mở một session mới cho mỗi request và đóng nó khi handler trả về.
Hạ tầng
Phần tiêu đề “Hạ tầng”Để cho phép hàm Lambda FastAPI kết nối với cơ sở dữ liệu tại runtime, nó phải được triển khai vào cùng VPC với cơ sở dữ liệu và được cấp quyền truy cập mạng và IAM.
Trong application stack của bạn, triển khai API vào cùng VPC với cơ sở dữ liệu, sau đó gọi allowDefaultPortFrom và grantConnect để mở đường dẫn mạng và cấp quyền IAM rds-db:connect cho Lambda handler:
import { MyDatabase } from '@my-scope/common-constructs';
const db = new MyDatabase(this, 'Db', { vpc, ... });
const api = new MyApi(this, 'Api', { integrations: MyApi.defaultIntegrations(this) .withDefaultOptions({ vpc, vpcSubnets: { subnetType: SubnetType.PRIVATE_WITH_EGRESS }, }) .build(),});
Object.entries(api.integrations).forEach(([operation, integration]) => { db.allowDefaultPortFrom(integration.handler, `Allow ${operation} to connect to the database`); db.grantConnect(integration.handler);});Triển khai các hàm Lambda API vào một private subnet với egress, không phải private isolated subnet. Tại runtime, session_context() lấy cấu hình cơ sở dữ liệu từ AWS AppConfig, đây là một public AWS service endpoint yêu cầu quyền truy cập internet ra ngoài.
Triển khai API vào cùng VPC với cơ sở dữ liệu, cấp cho nó rds-db:connect thông qua additional_iam_policy_statements, và mở đường dẫn mạng bằng một cặp security group rule:
Ví dụ dưới đây tham chiếu các tài nguyên VPC từ hướng dẫn triển khai Python Relational Database: các subnet aws_subnet.database không có internet route, trong khi các subnet aws_subnet.private có NAT egress.
module "my_database" { source = "../../common/terraform/src/app/dbs/my-database" vpc_id = aws_vpc.main.id database_subnet_ids = aws_subnet.database[*].id lambda_subnet_ids = aws_subnet.private[*].id}
module "api" { source = "../../common/terraform/src/app/apis/my-api" enable_vpc = true vpc_id = aws_vpc.main.id subnet_ids = aws_subnet.private[*].id
appconfig_application_id = module.runtime_config_appconfig.application_id appconfig_application_arn = module.runtime_config_appconfig.application_arn
additional_iam_policy_statements = [ { Effect = "Allow" Action = ["rds-db:connect"] Resource = [ "arn:aws:rds-db:${data.aws_region.current.region}:${data.aws_caller_identity.current.account_id}:dbuser:${module.my_database.connect_resource_id}/${module.my_database.database_runtime_user}" ] } ]}
resource "aws_vpc_security_group_ingress_rule" "api_to_database" { description = "Allow the API Lambda functions to connect to the database" security_group_id = module.my_database.security_group_id referenced_security_group_id = module.api.security_group_id from_port = module.my_database.cluster_port to_port = module.my_database.cluster_port ip_protocol = "tcp"}
resource "aws_vpc_security_group_egress_rule" "api_to_database" { description = "Allow outbound traffic from the API Lambda functions to the database" security_group_id = module.api.security_group_id referenced_security_group_id = module.my_database.security_group_id from_port = module.my_database.cluster_port to_port = module.my_database.cluster_port ip_protocol = "tcp"}Triển khai các hàm Lambda API vào private subnet với egress, không phải private isolated subnet. appconfig_application_id/appconfig_application_arn đến từ ứng dụng AppConfig runtime configuration được chia sẻ được khai báo một lần trong root module của bạn, không phải từ database module — việc truyền chúng sẽ đặt RUNTIME_CONFIG_APP_ID trên các hàm Lambda và cấp cho chúng quyền đọc vào ứng dụng.
Ứng dụng AppConfig expose namespace database theo mặc định, do đó entry runtime configuration của database module được triển khai mà không cần cấu hình thêm.
Yêu cầu SSL Khi Kết nối Không Sử dụng RDS Proxy
Phần tiêu đề “Yêu cầu SSL Khi Kết nối Không Sử dụng RDS Proxy”Kho lưu trữ tin cậy CA tích hợp sẵn của môi trường thực thi Lambda Amazon Linux 2023 bao gồm các Amazon Root CA được sử dụng bởi RDS, do đó không cần cấu hình bổ sung.
Khi sử dụng RDS Proxy, bạn không cần cấu hình gói CA của RDS trong hàm Lambda của mình.
Phát triển Cục bộ
Phần tiêu đề “Phát triển Cục bộ”pnpm nx dev <project-name>yarn nx dev <project-name>npx nx dev <project-name>bunx nx dev <project-name>Điều này khởi động FastAPI và tất cả các cơ sở dữ liệu được kết nối. Biến môi trường LOCAL_DEV=true khiến database client kết nối với cơ sở dữ liệu Docker cục bộ của nó thay vì Aurora.