Python 数据访问与 SQLAlchemy
数据访问层隔离 SQL/ORM;SQLAlchemy 为核心生态之一,需理解会话、事务与 N+1。
#type / concept
#status / growing
#tech / dev
#resource / python
#tech / lang / python
[!info] 关联笔记
Python 数据访问与 SQLAlchemy
这个概念为什么出现
业务若直接拼 SQL 字符串,会散落注入风险与事务边界混乱。数据访问层(Repository/DAO)+ ORM/查询构建器提供结构,但 ORM 不是免费午餐(N+1、隐式 IO)。
[!abstract] 一句话理解 把持久化细节关在数据层;SQLAlchemy 提供 Core/ORM,会话与事务界定工作单元,查询行为必须可观察。
最小可运行示例
场景:内存演示“仓储接口”而非真实 DB
# repo_pattern_demo.py
# 业务意图:用内存仓储表达数据层边界(无 DB 依赖)。
# 教学点:接口隔离;业务不拼存储细节。
from dataclasses import dataclass
@dataclass
class User:
id: str
email: str
class UserRepository:
def __init__(self) -> None:
self._rows: dict[str, User] = {}
def add(self, user: User) -> None:
self._rows[user.id] = user
def get(self, user_id: str) -> User | None:
return self._rows.get(user_id)
def register(repo: UserRepository, user_id: str, email: str) -> User:
user = User(user_id, email)
repo.add(user)
return user
def main() -> None:
repo = UserRepository()
register(repo, "u1", "a@example.com")
print(repo.get("u1"))
if __name__ == "__main__":
main()
建议运行:
python repo_pattern_demo.py
期望输出:
User(id='u1', email='a@example.com')
结合场景再看三个关注点
- 业务依赖仓储接口,便于测。
- 真实 SQLAlchemy:Engine/Session/映射。
- 谨防延迟加载触发隐式查询。
核心概念与准确模型
- Engine 连接池
- Session/Unit of Work
- Core SQL 表达式 vs ORM
- 迁移工具(Alembic)
边界情况与反直觉行为
- N+1
- 会话生命周期 与 web 请求绑定
- 跨进程身份映射
常见误区
[!warning] 常见误区:ORM 对象当跨层 DTO 到处传 错误理解:省转换。
正确模型:边界用明确 schema,避免会话剥离问题。
工程实践
- 事务边界清晰
- 慢查询日志
- 迁移版本化
本节总结
数据访问是正确性与性能交汇点。先边界,后 ORM 技巧。
自测题
- 仓储模式收益?
- N+1 是什么?
参考答案
- 业务与存储解耦、可测试。
- 循环中每次额外查询,放大延迟。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| SQLAlchemy | 文档 | ORM/Core |