一、概述
Python操作数据库一般有三种方式:
- 原生驱动直接写SQL:
sqlite3(内置SQLite)、pymysql(MySQL) - ORM框架 SQLAlchemy:用Python对象映射数据库表,减少手写SQL,适配多种数据库
- 适用场景:小测试用SQLite;业务存储用MySQL;项目开发优先SQLAlchemy
遵循数据库通用规范:先建连接 → 获取游标 → 执行SQL → 提交事务 → 关闭游标和连接
二、使用 SQLite
SQLite是文件型数据库,Python内置sqlite3模块,无需额外安装,不需要单独启动服务,适合本地测试、小型数据存储。
基础示例
import sqlite3
# 1. 连接数据库,不存在则自动创建文件 test.db
conn = sqlite3.connect("test.db")
# 2. 获取游标
cursor = conn.cursor()
# 建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER
)
''')
# 插入单条数据
cursor.execute("INSERT INTO user(name, age) VALUES (?, ?)", ("zhangsan", 20))
# 批量插入
cursor.executemany("INSERT INTO user(name, age) VALUES (?, ?)", [
("lisi", 22),
("wangwu", 21)
])
# 查询
cursor.execute("SELECT * FROM user")
print(cursor.fetchall()) # 全部结果
# cursor.fetchone() 取第一条
# cursor.fetchmany(2) 取前2条
# 更新
cursor.execute("UPDATE user SET age=? WHERE name=?", (25, "zhangsan"))
# 删除
cursor.execute("DELETE FROM user WHERE name=?", ("wangwu",))
# 提交事务(DML操作必须commit,SQLite默认事务)
conn.commit()
# 关闭
cursor.close()
conn.close()
占位符:SQLite 使用
?,不要用字符串拼接SQL,防止SQL注入
三、使用 MySQL
MySQL是C/S架构数据库,需要先安装MySQL服务,Python使用pymysql驱动。
1. 安装
pip install pymysql
2. 基础示例
import pymysql
# 建立连接
conn = pymysql.connect(
host="127.0.0.1",
port=3306,
user="root",
password="你的密码",
database="test_db",
charset="utf8mb4"
)
cursor = conn.cursor()
# 建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS user(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
''')
# 插入,pymysql占位符是 %s
cursor.execute("INSERT INTO user(name,age) VALUES (%s,%s)", ("zhangsan",20))
conn.commit()
# 查询
cursor.execute("SELECT * FROM user")
print(cursor.fetchall())
cursor.close()
conn.close()
✅ 重点区别:
- pymysql 占位符是
%s,不是字符串格式化! - 必须提前建好数据库(
CREATE DATABASE test_db;) - 异常场景:网络断开、账号密码错误、库不存在
异常捕获模板
import pymysql
try:
conn = pymysql.connect(...)
cursor = conn.cursor()
cursor.execute(sql)
conn.commit()
except pymysql.MySQLError as e:
print("数据库错误:", e)
conn.rollback() # 出错回滚
finally:
if conn:
cursor.close()
conn.close()
四、使用 SQLAlchemy
SQLAlchemy 是Python最经典的ORM(对象关系映射)框架,一套代码可以切换 SQLite / MySQL / PostgreSQL,不用大量改SQL。 分为两种使用方式:
- Core:SQL表达式方式
- ORM:面向对象,类映射表(日常开发最常用)
1. 安装
pip install sqlalchemy
2. ORM 完整示例(MySQL)
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker
# 1. 创建引擎,连接数据库
# mysql+pymysql://user:password@host:port/dbname
engine = create_engine("mysql+pymysql://root:密码@127.0.0.1:3306/test_db")
# SQLite引擎写法:engine = create_engine("sqlite:///test.db")
# 2. 基类,所有模型继承它
Base = declarative_base()
# 3. 定义模型类(对应数据库一张表)
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50), nullable=False)
age = Column(Integer)
def __repr__(self):
return f"<User(name={self.name}, age={self.age})>"
# 4. 创建表(不存在才创建)
Base.metadata.create_all(engine)
# 5. 创建会话,用来增删改查
Session = sessionmaker(bind=engine)
session = Session()
# 新增
u1 = User(name="zhangsan", age=20)
session.add(u1)
session.add_all([
User(name="lisi", age=22),
User(name="wangwu", age=21)
])
session.commit()
# 查询
# 查询所有
res = session.query(User).all()
# 条件查询
res = session.query(User).filter(User.name == "zhangsan").first()
# 模糊查询 filter(User.name.like("%zhang%"))
# 更新
if res:
res.age = 26
session.commit()
# 删除
session.delete(res)
session.commit()
session.close()
常用查询语法速记
# 等于
filter(User.name == "xxx")
# 大于小于
filter(User.age > 18)
# and / or
from sqlalchemy import or_, and_
filter(or_(User.age>20, User.name=="lisi"))
# 排序
order_by(User.age.desc())
# 分页 offset limit
session.query(User).order_by(User.id).offset(0).limit(10).all()
五、三者对比总结
| 方式 | 依赖 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|---|
| sqlite3 | 内置 | 零服务、开箱即用 | 并发弱、不适合多用户 | 本地缓存、脚本、测试 |
| pymysql原生 | 需要MySQL服务 | 灵活,完全掌控SQL | 重复样板代码,容易注入,切换数据库改动大 | 简单脚本、需要精细控制SQL |
| SQLAlchemy ORM | 驱动+框架 | 面向对象、跨数据库、防注入、代码优雅 | 有学习成本,复杂SQL性能不如手写 | Web项目、后端业务开发 |
六、重要注意事项
- 永远不要字符串拼接SQL,使用参数化查询,防止SQL注入
- 写修改操作(insert/update/delete)一定要
commit,异常时rollback - 用完连接、游标、session要关闭,避免连接泄漏
- MySQL注意编码
utf8mb4支持emoji - SQLAlchemy适合业务开发;报表、超复杂聚合SQL可以用原生SQL