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”pnpm nx g @aws/nx-plugin:connectionyarn nx g @aws/nx-plugin:connectionnpx nx g @aws/nx-plugin:connectionbunx nx g @aws/nx-plugin:connectionBạn cũng có thể thực hiện chạy thử để xem những tệp nào sẽ bị thay đổi
pnpm nx g @aws/nx-plugin:connection --dry-runyarn nx g @aws/nx-plugin:connection --dry-runnpx nx g @aws/nx-plugin:connection --dry-runbunx nx g @aws/nx-plugin:connection --dry-run- 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
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”| Tham số | Kiểu | Mặc định | Mô tả |
|---|---|---|---|
| sourceProject Bắt buộc | string | - | Dự án nguồn |
| targetProject Bắt buộc | string | - | Dự án đích để kết nối tới |
| sourceComponent | string | - | Component 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 generator id). Sử dụng '.' để chọn rõ ràng dự án làm nguồn. |
| targetComponent | string | - | Component đí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 generator id). Sử dụng '.' để chọn rõ ràng dự án làm đích. |
| preferInstallDependencies | boolean | true | Có 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))).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 phải expose namespace database để entry runtime configuration của database module được triển khai. Bao gồm nó trong namespaces khi khởi tạo module runtime-config/appconfig:
module "runtime_config_appconfig" { source = "../../common/terraform/src/core/runtime-config/appconfig"
application_name = "my-app-runtime-config" namespaces = ["connection", "agentcore", "database"]}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.