How to Use Tortoise ORM with FastAPI: Simple Setup Guide
To use
Tortoise ORM with FastAPI, install the package, define your models, and initialize Tortoise with FastAPI's startup and shutdown events. Use register_tortoise to connect your database and generate schemas automatically for async database operations.Syntax
This is the basic syntax to integrate Tortoise ORM with FastAPI:
register_tortoise(app, db_url, modules, generate_schemas, add_exception_handlers): Connects Tortoise ORM to FastAPI.db_url: Database connection string (e.g., SQLite, PostgreSQL).modules: Python modules where your models are defined.generate_schemas: If true, creates tables automatically on startup.add_exception_handlers: Adds handlers for database errors.
python
from fastapi import FastAPI from tortoise.contrib.fastapi import register_tortoise app = FastAPI() register_tortoise( app, db_url='sqlite://db.sqlite3', modules={'models': ['yourapp.models']}, generate_schemas=True, add_exception_handlers=True )
Example
This example shows a FastAPI app using Tortoise ORM with a simple User model. It demonstrates async database operations and automatic schema creation.
python
from fastapi import FastAPI from tortoise import fields, models from tortoise.contrib.fastapi import register_tortoise from pydantic import BaseModel app = FastAPI() class User(models.Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=50) class User_Pydantic(BaseModel): id: int name: str class UserIn_Pydantic(BaseModel): name: str @app.post('/users/', response_model=User_Pydantic) async def create_user(user: UserIn_Pydantic): user_obj = await User.create(**user.dict()) return await User_Pydantic.from_tortoise_orm(user_obj) @app.get('/users/{user_id}', response_model=User_Pydantic) async def get_user(user_id: int): user_obj = await User.get(id=user_id) return await User_Pydantic.from_tortoise_orm(user_obj) register_tortoise( app, db_url='sqlite://db.sqlite3', modules={'models': ['__main__']}, generate_schemas=True, add_exception_handlers=True )
Output
When running, POST /users/ with JSON {"name": "Alice"} creates a user and GET /users/1 returns {"id":1,"name":"Alice"}.
Common Pitfalls
- Forgetting to call
register_tortoisecauses no DB connection. - Not using async functions for DB calls leads to errors.
- Incorrect
modulespath prevents model discovery. - Not setting
generate_schemas=Truemeans tables won't be created automatically. - Using synchronous code with Tortoise ORM breaks async flow.
python
from fastapi import FastAPI from tortoise.contrib.fastapi import register_tortoise app = FastAPI() # Wrong: missing register_tortoise call @app.get('/') async def root(): return {"message": "Hello"} # Right way: register_tortoise( app, db_url='sqlite://db.sqlite3', modules={'models': ['yourapp.models']}, generate_schemas=True, add_exception_handlers=True )
Quick Reference
Key points to remember when using Tortoise ORM with FastAPI:
- Always use async functions for DB operations.
- Define models inheriting from
tortoise.models.Model. - Use
register_tortoiseto connect DB and auto-create tables. - Use Pydantic models for request/response validation.
- Set
generate_schemas=Trueduring development for auto migrations.
Key Takeaways
Use register_tortoise to connect Tortoise ORM with FastAPI and manage DB lifecycle.
Always write async functions for database queries with Tortoise ORM.
Define your models in modules and reference them correctly in register_tortoise.
Set generate_schemas=True during development to auto-create tables.
Use Pydantic models to serialize and validate data in FastAPI endpoints.