从 0 到 1 的 ORM 指南:Python+SQLAlchemy+MySQL

作为 Python 生态中最强大的 ORM 框架,SQLAlchemy 几乎是中大型 Python 项目的 “标配”—— 它能帮你用 Python 类操作 MySQL 数据库,彻底告别原生 SQL 的繁琐。

本文针对0 基础小白,从环境搭建→核心概念→CRUD 实战→关系映射,一步步讲清如何用 SQLAlchemy 连接 MySQL。全程代码可复制,每一行都有解释,目标是让你 “学完就能用”。

一、前置准备:环境搭好再开始

在写代码前,必须先搞定 3 件事:安装 MySQL、安装 Python 库、配置连接。

1. 安装 MySQL(新手推荐用 Docker,避免踩坑)

如果不想折腾 MySQL 的安装(比如 Windows 下的环境变量、权限问题),直接用 Docker 跑 MySQL——1 条命令就能启动:

# 启动MySQL 8.0容器(密码设为root123,端口映射3306) docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root123 mysql:8.0 

验证是否启动成功:

docker ps # 看mysql容器是否在运行 

2. 安装 Python 依赖库

需要两个库:

  • pymysql:Python 连接 MySQL 的驱动;
  • sqlalchemy:核心 ORM 框架。

用 pip 安装:

pip install pymysql sqlalchemy 

3. 测试 MySQL 连接(避免后续踩坑)

先写一段代码,验证能否连接到 MySQL:

from sqlalchemy import create_engine # MySQL连接字符串格式:mysql+pymysql://用户名:密码@主机:端口/数据库名 # 注意:首次连接需要先在MySQL中创建数据库(比如test_db) engine = create_engine('mysql+pymysql://root:root123@localhost:3306/test_db') # 测试连接(无报错则成功) with engine.connect() as conn: print("连接成功!") 

关键说明

  • 连接字符串中的test_db需要先在 MySQL 中创建(用 Navicat 或命令行CREATE DATABASE test_db;);
  • 如果用本地 MySQL 而非 Docker,hostlocalhost,密码填你安装时设置的密码。

二、SQLAlchemy 核心概念:3 个组件搞定 ORM

SQLAlchemy 的核心是 **“用对象封装数据库操作”**,你需要先理解 3 个关键组件:

1. Engine:数据库连接的 “总开关”

  • 作用:管理数据库连接池(不用每次操作都新建连接,提升性能);
  • 类比:像家里的 “总电源开关”,控制所有电器的供电。

创建 Engine 的代码:

from sqlalchemy import create_engine # 连接字符串格式:mysql+pymysql://用户名:密码@主机:端口/数据库名 engine = create_engine( 'mysql+pymysql://root:root123@localhost:3306/test_db', echo=True, # 打印执行的SQL(调试用,上线关闭) pool_size=5, # 连接池大小(默认5) max_overflow=10 # 超出连接池后的最大连接数(默认10) ) 

2. Base:所有模型的 “模板”

  • 作用:定义模型类的基类,自动映射类到数据库表;
  • 类比:像 “建筑图纸”,所有房子(模型类)都基于这个图纸建造。

创建 Base 的代码:

from sqlalchemy.orm import declarative_base # 创建模型基类(所有模型类都要继承它) Base = declarative_base() 

3. Session:操作数据库的 “把手”

  • 作用:负责和数据库交互(新增、查询、更新、删除);
  • 类比:像 “遥控器”,通过它控制电视(数据库)的操作。

创建 Session 的代码:

from sqlalchemy.orm import sessionmaker # 创建Session工厂(绑定Engine) SessionLocal = sessionmaker(bind=engine) # 获取Session实例(每次操作都要新建Session) session = SessionLocal() 

总结:Engine→连接池→Session→操作数据库;Base→模型类→表结构。

三、实战 1:定义第一个模型类 ——User 表

现在,我们用 Base 定义一个User类,对应 MySQL 的users表。

1. 定义模型类

from sqlalchemy import Column, Integer, String, DateTime from sqlalchemy.sql import func from datetime import datetime # 继承Base基类 class User(Base): __tablename__ = 'users' # 对应数据库的users表(必须小写) # 字段定义(Column是表字段的装饰器) id = Column(Integer, primary_key=True, index=True) # 主键(自增) name = Column(String(50), nullable=False) # 姓名(非空) email = Column(String(100), unique=True, index=True) # 邮箱(唯一,加索引) age = Column(Integer) # 年龄(可选) created_at = Column(DateTime(timezone=True), default=func.now()) # 创建时间(自动填充当前时间) 

关键说明

  • __tablename__:模型类对应的表名(必须和数据库中的表名一致,MySQL 默认小写);
  • primary_key=True:标记为主键(自增);
  • nullable=False:字段非空(插入数据时必须传值);
  • unique=True:字段唯一(避免重复邮箱);
  • func.now():用 MySQL 的NOW()函数自动填充当前时间(比 Python 的datetime.now()更准确)。

2. 创建表结构(让模型映射到数据库)

定义好模型类后,需要用 Base 创建表:

# 创建所有继承Base的模型对应的表(第一次运行时执行) Base.metadata.create_all(bind=engine) 

注意

  • 这段代码只会创建不存在的表(不会覆盖已有表);
  • 如果修改了模型类(比如新增字段),需要用迁移工具(如 Alembic)更新表结构(本文暂不展开)。

四、实战 2:CRUD 操作 —— 像 “操作 Python 对象” 一样操作数据库

现在,我们用 Session 实现增删改查,全程不用写 SQL!

1. 新增数据(Create)

# 创建User实例(相当于数据库中的一行数据) user = User(name='张三', email='[email protected]', age=18) # 将实例添加到Session(相当于“暂存”) session.add(user) # 提交Session(相当于“确认”,将数据写入数据库) session.commit() # 刷新实例(获取自增的id) session.refresh(user) print(f"新增用户ID:{user.id}") 

关键说明

  • add()只是将数据 “暂存” 到 Session,必须 commit () 才会写入数据库
  • refresh()会从数据库中获取最新数据(比如自增的 id)。

2. 查询数据(Read)

SQLAlchemy 提供了强大的查询 API,常用的有:

(1)根据主键查询(最常用)
# 根据id=1查询用户 user = session.get(User, 1) if user: print(f"用户姓名:{user.name},邮箱:{user.email}") else: print("用户不存在") 
(2)条件查询(比如查年龄≥18 的用户)
from sqlalchemy import select # 构建查询语句(SELECT * FROM users WHERE age >= 18) stmt = select(User).where(User.age >= 18) # 执行查询(返回所有符合条件的用户) users = session.execute(stmt).scalars().all() for user in users: print(f"ID:{user.id},姓名:{user.name}") 
(3)模糊查询(比如查姓名包含 “张” 的用户)
stmt = select(User).where(User.name.like('%张%')) users = session.execute(stmt).scalars().all() 

3. 更新数据(Update)

# 先查询要修改的用户 user = session.get(User, 1) # 修改属性 user.age = 20 user.email = '[email protected]' # 提交修改(自动生成UPDATE语句) session.commit() 

4. 删除数据(Delete)

# 先查询要删除的用户 user = session.get(User, 1) # 删除实例 session.delete(user) # 提交删除(自动生成DELETE语句) session.commit() 

五、实战 3:关系映射 —— 处理表之间的 “一对多” 关系

实际项目中,表之间一定有关系(比如用户和订单的 “一对多”),SQLAlchemy 能自动处理这些关系。

1. 定义关联模型(比如 Order 表)

class Order(Base): __tablename__ = 'orders' id = Column(Integer, primary_key=True, index=True) user_id = Column(Integer, ForeignKey('users.id')) # 外键(关联users表的id) product = Column(String(100), nullable=False) price = Column(Integer, nullable=False) created_at = Column(DateTime(timezone=True), default=func.now()) # 关系映射:Order→User(多对一) user = relationship('User', back_populates='orders') # back_populates指向User的orders属性 

2. 在 User 表中添加反向关系

class User(Base): __tablename__ = 'users' # 之前的字段... # 反向关系:User→Order(一对多) orders = relationship('Order', back_populates='user') # back_populates指向Order的user属性 

3. 测试关系映射

# 创建用户 user = User(name='李四', email='[email protected]', age=25) session.add(user) session.commit() # 创建订单(自动关联user_id) order1 = Order(user_id=user.id, product='手机', price=5999) order2 = Order(user_id=user.id, product='电脑', price=9999) session.add_all([order1, order2]) session.commit() # 查询用户的所有订单(通过user.orders) user = session.get(User, user.id) for order in user.orders: print(f"订单ID:{order.id},商品:{order.product},价格:{order.price}") 

关键说明

  • ForeignKey('users.id'):Order 表的user_id关联 User 表的id(外键约束);
  • relationship:定义模型之间的关系(比如 User 的orders属性会自动查询该用户的所有订单);
  • back_populates:双向关联(User 的orders和 Order 的user互相引用)。

六、进阶:优化与避坑 —— 小白必看!

1. 连接池配置(提升性能)

Engine 默认开启连接池(大小 5),可以通过create_engine的参数优化:

engine = create_engine( 'mysql+pymysql://root:root123@localhost:3306/test_db', pool_size=10, # 连接池大小(默认5) max_overflow=20, # 超出连接池后的最大连接数(默认10) pool_timeout=30, # 获取连接的超时时间(默认30秒) pool_recycle=1800 # 连接的存活时间(1800秒=30分钟,避免连接失效) ) 

2. 避免 SQL 注入(安全第一)

SQLAlchemy 的queryexecute方法会自动处理 SQL 注入(用参数化查询),禁止手动拼接 SQL

错误示例(会被 SQL 注入):

name = "张三'; DROP TABLE users; --" session.execute(f"SELECT * FROM users WHERE name='{name}'") # 危险! 

正确示例(参数化查询):

from sqlalchemy import text name = "张三'; DROP TABLE users; --" # 用text()和参数化查询 stmt = text("SELECT * FROM users WHERE name=:name") session.execute(stmt, {"name": name}) # 安全! 

3. 事务处理(避免数据不一致)

SQLAlchemy 的 Session 默认开启事务,必须 commit () 才会提交,rollback () 可以回滚:

try: user = User(name='王五', email='[email protected]') session.add(user) # 模拟错误(比如除以0) 1 / 0 session.commit() # 错误发生,不会执行 except Exception as e: session.rollback() # 回滚事务(取消之前的操作) print(f"错误:{e}") 

七、常见问题解答(小白踩坑高频区)

1. 连接报错 “Access denied for user 'root'@'localhost'”

  • 原因:密码错误或用户没有权限;

解决:检查连接字符串中的密码,或在 MySQL 中给 root 用户授权:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root123' WITH GRANT OPTION; FLUSH PRIVILEGES; 

2. 新增数据时报 “Duplicate entry '[email protected]' for key 'email'”

  • 原因:邮箱重复(unique=True约束);
  • 解决:确保插入的邮箱唯一,或在代码中处理重复错误。

3. 查询结果为空,但数据库中有数据

  • 原因:index=True需要先创建索引(或模型类的__tablename__写错);
  • 解决:检查模型类的__tablename__是否和数据库表名一致,或重新创建表(Base.metadata.drop_all()Base.metadata.create_all())。

八、总结:SQLAlchemy 的优势与适用场景

SQLAlchemy 是Python 中最强大的 ORM 框架,它的优势是:

  • 跨数据库支持:支持 MySQL、PostgreSQL、SQLite 等,切换数据库只需修改连接字符串;
  • 强大的查询 API:支持复杂查询(联表、分组、排序),不用写 SQL;
  • 事务管理:自动处理事务,避免数据不一致;
  • 性能优化:连接池、索引、延迟加载等功能提升性能。

适用场景

  • 中大型项目(需要复杂的数据库操作);
  • 多数据库切换(比如从 SQLite 迁移到 MySQL);
  • 需要事务管理和安全的项目(比如电商、金融)。

九、后续学习建议

  • 学习Alembic:数据库迁移工具(修改模型类后,自动更新表结构);
  • 学习SQLAlchemy Core:直接写 SQL 表达式(比 ORM 更灵活);
  • 学习查询优化:比如joinedload(预加载关联数据,避免 N+1 查询)。

最后,送你一句我用 SQLAlchemy 的经验:“ORM 是工具,不是银弹”—— 简单的查询可以用 ORM,复杂的查询(比如多表联查、统计)建议用 SQLAlchemy Core 或原生 SQL,平衡开发效率和性能。

Read more

最新电子电气架构(EEA)调研-3

而新一代的强实时性、高确定性,以及满足CAP定理的同步分布式协同技术(SDCT),可以实现替代TSN、DDS的应用,且此技术已经在无人车辆得到验证,同时其低成本学习曲线、无复杂二次开发工作,将开发人员的劳动强度、学习曲线极大降低,使开发人员更多的去完成算法、执行器功能完善。 五、各大车厂的EEA 我们调研策略是从公开信息中获得各大车厂的EEA信息,并在如下中进行展示。 我们集中了华为、特斯拉、大众、蔚来、小鹏、理想、东风(岚图)等有代表领先性的车辆电子电气架构厂商。        1、华为 图12 华为的CCA电子电气架构              (1)华为“计算+通信”CC架构的三个平台                         1)MDC智能驾驶平台;                         2)CDC智能座舱平台                         3)VDC整车控制平台。        联接指的是华为智能网联解决方案,解决车内、车外网络高速连接问题,云服务则是基于云计算提供的服务,如在线车主服务、娱乐和OTA等。 华

By Ne0inhk
Apache IoTDB 架构特性与 Prometheus+Grafana 监控体系部署实践

Apache IoTDB 架构特性与 Prometheus+Grafana 监控体系部署实践

Apache IoTDB 架构特性与 Prometheus+Grafana 监控体系部署实践 文章目录 * Apache IoTDB 架构特性与 Prometheus+Grafana 监控体系部署实践 * Apache IoTDB 核心特性与价值 * Apache IoTDB 监控面板完整部署方案 * 安装步骤 * 步骤一:IoTDB开启监控指标采集 * 步骤二:安装、配置Prometheus * 步骤三:安装grafana并配置数据源 * 步骤四:导入IoTDB Grafana看板 * TimechoDB(基于 Apache IoTDB)增强特性 * 总结与应用场景建议 Apache IoTDB 核心特性与价值 Apache IoTDB 专为物联网场景打造的高性能轻量级时序数据库,以 “设备 - 测点” 原生数据模型贴合物理设备与传感器关系,通过高压缩算法、百万级并发写入能力和毫秒级查询响应优化海量时序数据存储成本与处理效率,同时支持边缘轻量部署、

By Ne0inhk
SQL Server 2019安装教程(超详细图文)

SQL Server 2019安装教程(超详细图文)

SQL Server 介绍) SQL Server 是由 微软(Microsoft) 开发的一款 关系型数据库管理系统(RDBMS),支持结构化查询语言(SQL)进行数据存储、管理和分析。自1989年首次发布以来,SQL Server 已成为企业级数据管理的核心解决方案,广泛应用于金融、电商、ERP、CRM 等业务系统。它提供高可用性、安全性、事务处理(ACID)和商业智能(BI)支持,并支持 Windows 和 Linux 跨平台部署。 一、获取 SQL Server 2019 安装包 1. 官方下载方式 前往微软官网注册账号后,即可下载 SQL Server Developer 版本(

By Ne0inhk