照例先看层次图
一、声明映射关系
使用 ORM 时,我们首先需要定义要操作的表(通过 Table
),然后再定义该表对应的 Python class,并声明两者之间的映射关系(通过 Mapper
)。
方便起见,SQLAlchemy 提供了 Declarative 系统来一次完成上述三个步骤,Declarative 系统提供 base class,这个 base class 会为继承了它的 Python class(可称作 model)创建 Table,并维护两者的映射关系。
from sqlalchemy.ext.declarative import declarative_base
from SQLAlchemy import Column, Integer, String
Base = declarative_base() # 拿到 Base 类
class User(Base):
id = Column(Integer, primary_key=True)
username = Column(String(32), nullable=False, index=True) # 添加 index 提升搜索效率
fullname = Column(String(64))
password = Column(String(32)) # 真实情况下一般只存 hash
def __repr__(self):
return f"<User {self.username}>"
这样就声明好了一个对象-关系映射,上一篇文章说过所有的 Table 都在某个 MetaData 中,可以通过 Base.metadata
获取它。
Base.metadata.create_all(engine) # 通过 metadata 创建表(或者说生成模式 schema)
二、获取 session
上一节讲 engine 时,我们是通过 connection 来与数据库交互,而在 ORM 中我们使用 Session 访问数据库。
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine) # 获取 session
三、增删改
- 增添:
ed_user = User(name='ed', fullname='Ed Jones', password='edspassword') # 用构造器构造对象
session.add(ed_user) # 添加,此外还有批量添加 add_all([user1, user2...])
session.commit() # 必须手动 commit
- 修改:
ed_user = session.query(User).filter_by(name='ed').first() # 先获取到 User 对象
ed_user.password = 'f8s7ccs' # 改了密码
session.commit() # 提交
- 删除:
ed_user = session.query(User).filter_by(name='ed').first() # 先获取到 User 对象
session.delete(ed_user) # 直接删除(session 知道 ed_user 属于哪个表)
session.commit() # 提交
同样的,也可以在外面检查异常,然后调用 session.rollback()
实现失败回滚。
四、进阶查询
- filter_by
待续
五、关系构建(relationship、foreign key)
待续
Further More
数据库迁移:alembic