惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threatpost
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Forbes - Security
Forbes - Security
人人都是产品经理
人人都是产品经理
N
Netflix TechBlog - Medium
Recent Commits to openclaw:main
Recent Commits to openclaw:main
WordPress大学
WordPress大学
Webroot Blog
Webroot Blog
Jina AI
Jina AI
H
Hacker News: Front Page
Attack and Defense Labs
Attack and Defense Labs
T
Troy Hunt's Blog
TaoSecurity Blog
TaoSecurity Blog
AI
AI
Hacker News - Newest:
Hacker News - Newest: "LLM"
Google Online Security Blog
Google Online Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Help Net Security
Help Net Security
美团技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 叶小钗
P
Privacy International News Feed
A
Arctic Wolf
IT之家
IT之家
云风的 BLOG
云风的 BLOG
S
Security Affairs
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
博客园 - 司徒正美
Vercel News
Vercel News
C
Cyber Attacks, Cyber Crime and Cyber Security
SecWiki News
SecWiki News
K
Kaspersky official blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
N
News and Events Feed by Topic
S
Schneier on Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
有赞技术团队
有赞技术团队
PCI Perspectives
PCI Perspectives
F
Fortinet All Blogs
T
Tenable Blog
Spread Privacy
Spread Privacy
T
The Blog of Author Tim Ferriss
S
Securelist
L
LangChain Blog
Latest news
Latest news
Cloudbric
Cloudbric
博客园 - 三生石上(FineUI控件)

博客园 - work hard work smart

使用 LangChain + Hugging Face 构建文本向量化服务 Python 中使用 Elasticsearch 的完整指南 Qdrant 向量数据库使用指南 OpenEvals 快速入门:LLM 评估指南 DeepEval 快速入门:LLM 应用评估指南 LangSmith 批量评估完全指南 Qwen-Agent 入门指南:快速构建智能体应用 LangSmith 集成实战:从追踪到评估的完整指南 初识 go-zero:一款让你写后端更规范、更高效的 Go 微服务框架 RAG 中为什么需要 Rerank,以及如何使用 Rerank LangChain4j RAG 核心组件与组合方式 如何使用 Elasticsearch 进行全文检索和向量检索 MinerU Docker 部署指南 5 分钟上手:为 Cline 配置一个免费的 MCP 天气服务 Neo4j 图数据库安装与 Spring Boot 集成实战指南 LangFuse 实战指南:用 @observe 三行代码给 LLM 应用加上全链路追踪 Function Call 深度解析:让大模型从"嘴炮"到"实干"的技术革命 Spring AI 提示词模板实战:告别硬编码,实现提示词工程化管理 LangChain4j 实战指南:用 Java 轻松构建 AI 应用 Spring AI 对话短期记忆实战:让大模型拥有"记忆力" Spring AI 提示词工程实战:让大模型更懂你的意图 Spring AI ChatClient 深度解析:优雅构建大模型应用的利器 Spring AI Alibaba DashScopeChatModel 实战 Spring 中 SSE 流式输出的多种实现方式详解 OpenSandbox 实战指南:为 AI Agent 构建安全的代码执行沙箱 在本机启动 LangGraph 开发服务器:完整指南 DeepAgents中Backend的奥秘:让AI Agent拥有文件操作能力 为什么选择 Go 开发 Web 接口?从入门到实践 智能搜索DeepAgent笔记 RAG学习笔记2--系统查询流程 RAG学习笔记1--系统文件导入流程 百炼 WebSearch 快速入门指南 Python 连接 MongoDB 完整指南:从连接配置到增删改查实战 一行命令搞定 MongoDB 开发环境:Docker Compose 部署 + 可视化管理 使用 Attu 可视化管理 Milvus 向量数据库 在 Windows Docker 中快速安装 Milvus 2.5.6 minio使用 Spark 集群搭建 hadoop集群安装 Spring AI Alibaba 入门实战 Windows 安装 OpenClaw 实战指南 MyBatis 核心流程和原理 Idea中安装Claude code插件 Spark 编程 使用Matplotlib 绘制直方图 Flink安装部署 Flume安装 查找导致cpu过高的代码方法 JVisualVM监控远程Java进程 jmap jacoco多模块生成java单元测试报告实践 arthas 使用demo LockSupport Exchanger CyclicBarrier CountDownLatch 手把手教你用python开始第一个机器学习项目
SQLAlchemy 使用详解
work hard work smart · 2026-07-05 · via 博客园 - work hard work smart

SQLAlchemy 使用详解

SQLAlchemy 是 Python 中最强大的 ORM(对象关系映射)工具之一,提供了强大的查询功能、事务管理和数据映射能力。本文将介绍 SQLAlchemy 的通用使用方法,帮助开发者构建健壮的数据访问层。

1. 架构概述

使用 SQLAlchemy 时,通常采用以下架构模式:

数据访问层架构
+---------------------+
|   实体层 (Entities)  |
|   定义业务对象结构   |
+---------------------+
          ↓
+---------------------+
|   映射层 (Mappers)   |
| 实体与数据库模型映射 |
+---------------------+
          ↓
+---------------------+
|  数据库模型 (Models)  |
|  SQLAlchemy 映射类   |
+---------------------+
          ↓
+---------------------+
|   存储库 (Repositories) |
| 数据访问操作接口   |
+---------------------+
          ↓
+---------------------+
| 连接管理器 (Client Manager) |
| 数据库连接与会话管理 |
+---------------------+

2. SQLAlchemy 核心组件

2.1 连接管理

from sqlalchemy.ext.asyncio import create_async_engine, AsyncEngine, AsyncSession, async_sessionmaker

class MySQLClientManager:
    def __init__(self, config: dict):
        self.engine: AsyncEngine | None = None
        self.session_factory = None
        self.config = config

    def _get_url(self):
        base_url = f"mysql+asyncmy://{self.config['user']}:{self.config['password']}@" \
                  f"{self.config['host']}:{self.config['port']}"
        if self.config.get('database'):
            base_url += f"/{self.config['database']}"
        base_url += "?charset=utf8mb4"
        return base_url

    def init(self):
        self.engine = create_async_engine(self._get_url(), pool_size=10, pool_pre_ping=True)
        self.session_factory = async_sessionmaker(self.engine, autoflush=True, expire_on_commit=False)

    async def close(self):
        await self.engine.dispose()

关键特性

  • 使用 sqlalchemy.ext.asyncio 实现异步操作
  • 配置连接池管理(pool_size=10
  • 启用连接检查(pool_pre_ping=True
  • 支持灵活的数据库连接配置

2.2 基础模型类

from sqlalchemy.orm import DeclarativeBase

class Base(DeclarativeBase):
    pass

说明

  • 定义了 SQLAlchemy 的基础模型类
  • 所有数据库模型都继承自此类
  • 使用 DeclarativeBase 简化模型定义

2.3 数据库模型

from sqlalchemy import String, Text, Integer, DateTime
from sqlalchemy.orm import Mapped, mapped_column
from datetime import datetime

class TableInfo(Base):
    __tablename__ = "table_info"
    __table_args__ = {"extend_existing": True}

    id: Mapped[str] = mapped_column(
        String(64),
        primary_key=True,
        comment="表编号"
    )
    name: Mapped[str | None] = mapped_column(
        String(128),
        comment="表名称"
    )
    role: Mapped[str | None] = mapped_column(
        String(32),
        comment="表类型(fact/dim)"
    )
    description: Mapped[str | None] = mapped_column(
        Text,
        comment="表描述"
    )
    database: Mapped[str | None] = mapped_column(
        String(64),
        default="default_db",
        comment="所属数据库名称"
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=datetime.now,
        comment="创建时间"
    )

模型特性

  • 使用类型注解风格的 Mappedmapped_column
  • 支持非空字段和默认值
  • 提供数据库字段注释
  • 配置表扩展属性 (extend_existing)

3. 数据访问与操作

3.1 实体与模型映射

项目采用数据映射模式,将业务实体与数据库模型分离:

class TableInfoEntity:
    """表信息实体类"""
    
    def __init__(self, id: str, name: str = None, role: str = None, 
                 description: str = None, database: str = None):
        self.id = id
        self.name = name
        self.role = role
        self.description = description
        self.database = database


class TableInfoMapper:
    """TableInfo 实体与模型之间的映射类"""
    
    @staticmethod
    def to_model(entity: TableInfoEntity) -> TableInfo:
        """将实体转换为数据库模型"""
        return TableInfo(
            id=entity.id,
            name=entity.name,
            role=entity.role,
            description=entity.description,
            database=entity.database
        )
    
    @staticmethod
    def to_entity(model: TableInfo) -> TableInfoEntity:
        """将数据库模型转换为实体"""
        return TableInfoEntity(
            id=model.id,
            name=model.name,
            role=model.role,
            description=model.description,
            database=model.database
        )

3.2 存储库模式

from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession

class MySQLRepository:
    """
    MySQL 通用存储库类

    负责与 MySQL 数据库交互,提供通用的数据访问接口。
    """

    def __init__(self, session: AsyncSession):
        """
        初始化 MySQL 存储库

        Args:
            session: SQLAlchemy 异步会话对象
        """
        self.session = session

    async def save_entity(self, entity: TableInfoEntity):
        """
        保存或更新实体到 MySQL 数据库

        Args:
            entity: 实体对象
        """
        existing = await self.session.get(TableInfo, entity.id)
        if existing:
            # 如果已存在,更新信息
            existing.name = entity.name
            existing.role = entity.role
            existing.description = entity.description
            existing.database = entity.database
        else:
            # 如果不存在,插入新记录
            self.session.add(TableInfoMapper.to_model(entity))

    async def get_entity_by_id(self, id: str) -> TableInfoEntity | None:
        """
        根据 ID 查询实体

        Args:
            id: 实体 ID

        Returns:
            TableInfoEntity | None: 实体对象,若不存在则返回 None
        """
        model = await self.session.get(TableInfo, id)
        if model:
            return TableInfoMapper.to_entity(model)
        else:
            return None

    async def get_all_entities(self) -> list[TableInfoEntity]:
        """
        查询所有实体

        Returns:
            list[TableInfoEntity]: 实体列表
        """
        from sqlalchemy.future import select
        result = await self.session.execute(select(TableInfo))
        return [TableInfoMapper.to_entity(row[0]) for row in result]

关键特性

  • 提供统一的数据访问接口
  • 支持实体与模型之间的自动映射
  • 实现了常用的 CRUD 操作
  • 使用 SQLAlchemy 会话管理事务

4. 会话管理

在实际使用中,我们使用异步会话工厂来管理数据库会话:

import asyncio
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine

# 配置数据库连接
config = {
    "host": "localhost",
    "port": 3306,
    "user": "root",
    "password": "password",
    "database": "mydatabase"
}

# 初始化连接管理器
manager = MySQLClientManager(config)
manager.init()

async def test_query():
    async with manager.session_factory() as session:
        try:
            repo = MySQLRepository(session)
            
            # 测试查询所有表信息
            tables = await repo.get_all_entities()
            print(f"查询到 {len(tables)} 条表信息")
            if tables:
                print(f"第一条记录: {tables[0].name}")
        except Exception as e:
            print(f"查询失败: {e}")

asyncio.run(test_query())

会话管理模式

  • 使用异步上下文管理器自动管理会话
  • 确保会话正确关闭和资源释放
  • 支持事务管理

5. 高级查询功能

SQLAlchemy 提供了强大的查询 API,支持各种查询操作:

from sqlalchemy.future import select

# 查询所有表信息
async def get_all_tables():
    async with manager.session_factory() as session:
        repo = MySQLRepository(session)
        return await repo.get_all_entities()

# 查询特定类型的表
async def get_specific_tables(role: str):
    async with manager.session_factory() as session:
        result = await session.execute(
            select(TableInfo).where(TableInfo.role == role)
        )
        return [TableInfoMapper.to_entity(row[0]) for row in result]

# 使用原生 SQL 查询
async def get_tables_with_sql():
    async with manager.session_factory() as session:
        sql = "select * from table_info where role in ('fact', 'dim')"
        result = await session.execute(text(sql))
        return [TableInfo(**dict(row)) for row in result.mappings().fetchall()]

6. 性能优化技巧

6.1 连接池配置

def init(self):
    self.engine = create_async_engine(
        self._get_url(),
        pool_size=20,
        max_overflow=10,
        pool_recycle=3600,
        pool_pre_ping=True
    )
    self.session_factory = async_sessionmaker(self.engine, autoflush=True, expire_on_commit=False)

优化建议

  • 根据实际并发量调整 pool_size
  • 使用 max_overflow 处理突发请求
  • 设置 pool_recycle 防止连接过期
  • 使用 pool_pre_ping 确保连接有效性

6.2 查询优化

# 批量查询示例
async def get_tables_by_ids(table_ids: list[str]) -> list[TableInfoEntity]:
    async with manager.session_factory() as session:
        result = await session.execute(
            select(TableInfo).where(TableInfo.id.in_(table_ids))
        )
        return [TableInfoMapper.to_entity(row[0]) for row in result]

7. 错误处理与调试

7.1 错误处理

import logging

async def safe_query(query_func):
    """安全查询装饰器"""
    async def wrapper(*args, **kwargs):
        try:
            return await query_func(*args, **kwargs)
        except Exception as e:
            logging.error(f"查询失败: {str(e)}", exc_info=True)
            return None
    return wrapper

@safe_query
async def get_safe_table_info(table_id: str) -> TableInfoEntity:
    """安全查询表信息"""
    async with manager.session_factory() as session:
        repo = MySQLRepository(session)
        return await repo.get_entity_by_id(table_id)

7.2 查询调试

使用 SQLAlchemy 的查询日志功能:

import logging

# 配置 SQLAlchemy 日志
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

# 查询时会打印 SQL 语句
async with manager.session_factory() as session:
    result = await session.execute(select(TableInfo))
    print(f"查询到 {result.scalar_one_or_none()} 条记录")

8. 最佳实践

8.1 分层架构

遵循清晰的分层架构:

  • 实体层:定义业务对象结构
  • 映射层:处理实体与模型的转换
  • 存储库层:提供数据访问接口
  • 服务层:处理业务逻辑

8.2 会话管理

  • 始终使用上下文管理器管理会话
  • 避免在长时间运行的操作中保持会话
  • 合理设置会话超时时间

8.3 查询优化

  • 避免 N+1 查询问题,使用 selectinloadjoinedload 预加载
  • 合理使用索引
  • 避免不必要的字段查询,只查询需要的数据

8.4 事务管理

  • 使用异步上下文管理器处理事务
  • 确保事务边界正确
  • 处理事务异常和回滚

9. 总结

SQLAlchemy 提供了一个强大、灵活且可靠的数据库访问层。通过使用异步操作、连接池管理和高级查询功能,我们能够处理各种复杂的数据访问需求。同时,采用实体-模型映射和存储库模式,使代码结构清晰、易于维护和扩展。

在实际项目中,还可以根据具体需求进一步优化查询性能、增加缓存策略和监控机制,以确保数据访问层的高可用性和响应性。