Python 數(shù)據(jù)庫操作神器,一文掌握 ORM!
你是否遇到這些問題?
- 還在手寫 SQL?數(shù)據(jù)庫操作太麻煩?
- Django ORM 用過,但想在 Flask 中也用 ORM?
- SQLAlchemy 怎么連接數(shù)據(jù)庫?如何查詢數(shù)據(jù)?
SQLAlchemy 是 Python 最強大的 ORM 框架,支持 MySQL、PostgreSQL、SQLite、SQL Server 等數(shù)據(jù)庫。本篇文章帶你 從入門到實戰(zhàn),徹底掌握 SQLAlchemy!
1. 什么是 SQLAlchemy?為什么要用 ORM?
SQLAlchemy 是 Python 的 ORM(對象關系映射)框架,可以用 Python 代碼 直接操作數(shù)據(jù)庫,而 不需要寫 SQL。
為什么要用 ORM?
- 數(shù)據(jù)庫操作更 Pythonic(面向對象)
- 兼容多種數(shù)據(jù)庫(MySQL、PostgreSQL、SQLite 等)
- 自動生成 SQL,避免 SQL 注入風險
- 更易維護,代碼比 SQL 語句更清晰
傳統(tǒng) SQL 操作(手寫 SQL):
import sqlite3
conn = sqlite3.connect("test.db")
cursor = conn.cursor()
cursor.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)")
cursor.execute("INSERT INTO users (name, age) VALUES ('Alice', 25)")
conn.commit()
cursor.close()
conn.close()
SQLAlchemy 操作(ORM 方式):
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker
engine = create_engine("sqlite:///test.db")
Base = declarative_base()
classUser(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
new_user = User(name="Alice", age=25)
session.add(new_user)
session.commit()
SQLAlchemy 讓數(shù)據(jù)庫操作更清晰、更 Pythonic!
2. 安裝 & 配置 SQLAlchemy
(1) 安裝 SQLAlchemy
pip install sqlalchemy
如果使用 MySQL,需要額外安裝 MySQL 驅動:
pip install pymysql
(2) 創(chuàng)建數(shù)據(jù)庫連接
from sqlalchemy import create_engine
# 連接 SQLite
engine = create_engine("sqlite:///test.db")
# 連接 MySQL(需要安裝 pymysql)
# engine = create_engine("mysql+pymysql://user:password@localhost/dbname")
SQLAlchemy 通過 create_engine() 統(tǒng)一管理數(shù)據(jù)庫連接!
3. 創(chuàng)建 ORM 模型(定義數(shù)據(jù)表)
定義一個 User 表:
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False)
age = Column(Integer)
# 創(chuàng)建表
Base.metadata.create_all(engine)
ORM 方式定義表結構,避免手寫 SQL !
4. CRUD 操作(增刪改查)
(1) 創(chuàng)建數(shù)據(jù)庫會話
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
所有數(shù)據(jù)庫操作都通過 session 進行!
(2) 插入數(shù)據(jù)(Create)
new_user = User(name="Alice", age=25)
session.add(new_user)
session.commit()
使用 session.add() 添加新數(shù)據(jù),commit() 提交!
(3) 查詢數(shù)據(jù)(Read)
- 查詢所有用戶
users = session.query(User).all()
for user in users:
print(user.id, user.name, user.age)
- 按條件查詢
user = session.query(User).filter_by(name="Alice").first()
print(user.id, user.name, user.age)
- 多條件查詢
from sqlalchemy import and_, or_
# 年齡 > 20 且姓名是 Alice
users = session.query(User).filter(and_(User.age > 20, User.name == "Alice")).all()
# 年齡 > 20 或 姓名是 Alice
users = session.query(User).filter(or_(User.age > 20, User.name == "Alice")).all()
filter() 方式類似 SQL WHERE 語句!
(4) 更新數(shù)據(jù)(Update)
user = session.query(User).filter_by(name="Alice").first()
user.age = 30
session.commit()
直接修改對象屬性,再 commit() 保存!
(5) 刪除數(shù)據(jù)(Delete)
user = session.query(User).filter_by(name="Alice").first()
session.delete(user)
session.commit()
使用 session.delete() 刪除對象!
5. 進階操作:一對多 & 多對多
(1) 一對多關系(User → Post)
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
class Post(Base):
__tablename__ = "posts"
id = Column(Integer, primary_key=True)
title = Column(String(100))
user_id = Column(Integer, ForeignKey("users.id"))
user = relationship("User", back_populates="posts")
User.posts = relationship("Post", order_by=Post.id, back_populates="user")
relationship() 讓表之間建立關系,查詢時更方便!
(2) 多對多關系(User ? Course)
from sqlalchemy import Table
# 關聯(lián)表
user_course = Table(
"user_course", Base.metadata,
Column("user_id", Integer, ForeignKey("users.id")),
Column("course_id", Integer, ForeignKey("courses.id"))
)
classCourse(Base):
__tablename__ = "courses"
id = Column(Integer, primary_key=True)
name = Column(String(100))
users = relationship("User", secondary=user_course, back_populates="courses")
User.courses = relationship("Course", secondary=user_course, back_populates="users")
多對多關系通過 secondary 關聯(lián)表實現(xiàn)!
6. SQLAlchemy vs 直接寫 SQL,哪種更好?
方式 | ORM(SQLAlchemy) | 手寫 SQL |
代碼可讀性 | ? 高,可維護性好 | ? 低,SQL 語句較長 |
數(shù)據(jù)庫兼容性 | ? 兼容 MySQL、PostgreSQL、SQLite | ? 需改寫 SQL 適配不同數(shù)據(jù)庫 |
安全性 | ? 避免 SQL 注入 | ? 需手動防 SQL 注入 |
性能 | ? ORM 有一定性能損耗 | ? SQL 執(zhí)行更快 |
開發(fā)效率 | ? 高效,操作數(shù)據(jù)庫像操作對象 | ? 需要手寫 SQL |
- 小型項目、簡單查詢 → ORM 更方便!
- 復雜查詢、大數(shù)據(jù)量操作 → SQL 更高效!
7. 結語:SQLAlchemy 讓 Python 操作數(shù)據(jù)庫更簡單!
- ORM 讓數(shù)據(jù)庫操作更直觀,不用手寫 SQL!
- SQLAlchemy 適用于大部分項目,靈活易用,功能強大!