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 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ó:
- Một dự án
py#fast-api - Một dự án
py#rdb
Cách sử dụng
Phần tiêu đề “Cách sử dụng”Chạy Generator
Phần tiêu đề “Chạy Generator”- 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
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-runChọ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ẽ sửa đổi dự án FastAPI của bạn:
Thư mụcpackages/my_api
- project.json Thêm dependency từ
devvào targetdevcủa cơ sở dữ liệu - pyproject.toml Thêm gói cơ sở dữ liệu làm dependency workspace
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 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 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 endpoint dịch vụ AWS công khai 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ó quyền rds-db:connect thông qua additional_iam_policy_statements, và mở đường dẫn mạng bằng một cặp quy tắc security group:
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}
module "api" { source = "..." enable_vpc = true vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnet_ids
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}" ] } ]
env = { RUNTIME_CONFIG_APP_ID = module.runtime_config_appconfig.application_id }}
resource "aws_vpc_security_group_ingress_rule" "api_to_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" { 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. RUNTIME_CONFIG_APP_ID nên trỏ đến ứng dụng AppConfig runtime configuration được chia sẻ, không phải output của database module.
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>Lệnh 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.