python-database-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePython Database Patterns
Python 数据库模式
SQLAlchemy 2.0 and database best practices.
SQLAlchemy 2.0 与数据库最佳实践。
SQLAlchemy 2.0 Basics
SQLAlchemy 2.0 基础
python
from sqlalchemy import create_engine, select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(100))
email: Mapped[str] = mapped_column(String(255), unique=True)
is_active: Mapped[bool] = mapped_column(default=True)python
from sqlalchemy import create_engine, select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(100))
email: Mapped[str] = mapped_column(String(255), unique=True)
is_active: Mapped[bool] = mapped_column(default=True)Create engine and tables
Create engine and tables
engine = create_engine("postgresql://user:pass@localhost/db")
Base.metadata.create_all(engine)
engine = create_engine("postgresql://user:pass@localhost/db")
Base.metadata.create_all(engine)
Query with 2.0 style
Query with 2.0 style
with Session(engine) as session:
stmt = select(User).where(User.is_active == True)
users = session.execute(stmt).scalars().all()
undefinedwith Session(engine) as session:
stmt = select(User).where(User.is_active == True)
users = session.execute(stmt).scalars().all()
undefinedAsync SQLAlchemy
异步 SQLAlchemy
python
from sqlalchemy.ext.asyncio import (
AsyncSession,
async_sessionmaker,
create_async_engine,
)
from sqlalchemy import selectpython
from sqlalchemy.ext.asyncio import (
AsyncSession,
async_sessionmaker,
create_async_engine,
)
from sqlalchemy import selectAsync engine
Async engine
engine = create_async_engine(
"postgresql+asyncpg://user:pass@localhost/db",
echo=False,
pool_size=5,
max_overflow=10,
)
engine = create_async_engine(
"postgresql+asyncpg://user:pass@localhost/db",
echo=False,
pool_size=5,
max_overflow=10,
)
Session factory
Session factory
async_session = async_sessionmaker(engine, expire_on_commit=False)
async_session = async_sessionmaker(engine, expire_on_commit=False)
Usage
Usage
async with async_session() as session:
result = await session.execute(select(User).where(User.id == 1))
user = result.scalar_one_or_none()
undefinedasync with async_session() as session:
result = await session.execute(select(User).where(User.id == 1))
user = result.scalar_one_or_none()
undefinedModel Relationships
模型关系
python
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, Mapped, mapped_column
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
# One-to-many
posts: Mapped[list["Post"]] = relationship(back_populates="author")
class Post(Base):
__tablename__ = "posts"
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
author_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
# Many-to-one
author: Mapped["User"] = relationship(back_populates="posts")python
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, Mapped, mapped_column
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
# One-to-many
posts: Mapped[list["Post"]] = relationship(back_populates="author")
class Post(Base):
__tablename__ = "posts"
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
author_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
# Many-to-one
author: Mapped["User"] = relationship(back_populates="posts")Common Query Patterns
常见查询模式
python
from sqlalchemy import select, and_, or_, funcpython
from sqlalchemy import select, and_, or_, funcBasic select
Basic select
stmt = select(User).where(User.is_active == True)
stmt = select(User).where(User.is_active == True)
Multiple conditions
Multiple conditions
stmt = select(User).where(
and_(
User.is_active == True,
User.age >= 18
)
)
stmt = select(User).where(
and_(
User.is_active == True,
User.age >= 18
)
)
OR conditions
OR conditions
stmt = select(User).where(
or_(User.role == "admin", User.role == "moderator")
)
stmt = select(User).where(
or_(User.role == "admin", User.role == "moderator")
)
Ordering and limiting
Ordering and limiting
stmt = select(User).order_by(User.created_at.desc()).limit(10)
stmt = select(User).order_by(User.created_at.desc()).limit(10)
Aggregates
Aggregates
stmt = select(func.count(User.id)).where(User.is_active == True)
stmt = select(func.count(User.id)).where(User.is_active == True)
Joins
Joins
stmt = select(User, Post).join(Post, User.id == Post.author_id)
stmt = select(User, Post).join(Post, User.id == Post.author_id)
Eager loading
Eager loading
from sqlalchemy.orm import selectinload
stmt = select(User).options(selectinload(User.posts))
undefinedfrom sqlalchemy.orm import selectinload
stmt = select(User).options(selectinload(User.posts))
undefinedFastAPI Integration
FastAPI 集成
python
from fastapi import Depends, FastAPI
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Annotated
async def get_db() -> AsyncGenerator[AsyncSession, None]:
async with async_session() as session:
yield session
DB = Annotated[AsyncSession, Depends(get_db)]
@app.get("/users/{user_id}")
async def get_user(user_id: int, db: DB):
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404)
return userpython
from fastapi import Depends, FastAPI
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Annotated
async def get_db() -> AsyncGenerator[AsyncSession, None]:
async with async_session() as session:
yield session
DB = Annotated[AsyncSession, Depends(get_db)]
@app.get("/users/{user_id}")
async def get_user(user_id: int, db: DB):
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404)
return userQuick Reference
快速参考
| Operation | SQLAlchemy 2.0 Style |
|---|---|
| Select all | |
| Filter | |
| First | |
| All | |
| Count | |
| Join | |
| Eager load | |
| 操作 | SQLAlchemy 2.0 风格 |
|---|---|
| 查询全部 | |
| 过滤 | |
| 获取单个或None | |
| 获取全部 | |
| 计数 | |
| 连接 | |
| 预加载 | |
Additional Resources
额外资源
- - Async patterns, session management
./references/sqlalchemy-async.md - - Pool configuration, health checks
./references/connection-pooling.md - - Transaction patterns, isolation levels
./references/transactions.md - - Alembic setup, migration strategies
./references/migrations.md
- - 异步模式、会话管理
./references/sqlalchemy-async.md - - 连接池配置、健康检查
./references/connection-pooling.md - - 事务模式、隔离级别
./references/transactions.md - - Alembic 配置、迁移策略
./references/migrations.md
Assets
资源文件
- - Alembic configuration template
./assets/alembic.ini.template
- - Alembic 配置模板
./assets/alembic.ini.template
See Also
另请参阅
Prerequisites:
- - Mapped types and annotations
python-typing-patterns - - Async database sessions
python-async-patterns
Related Skills:
- - Dependency injection for DB sessions
python-fastapi-patterns - - Database fixtures and testing
python-pytest-patterns
前置要求:
- - 映射类型与注解
python-typing-patterns - - 异步数据库会话
python-async-patterns
相关技能:
- - 数据库会话的依赖注入
python-fastapi-patterns - - 数据库 fixtures 与测试
python-pytest-patterns