关系属性
定义
# 用户表 一 一个用户可以有多个地址
class User(db.Model):
__tablename__ = 't_user'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
# 1.定义关系属性 relationship("关联的类名")
addresses = db.relationship('Address')
# 地址表 多
class Address(db.Model):
__tablename__ = 't_adr'
id = db.Column(db.Integer, primary_key=True)
detail = db.Column(db.String(20))
# 2. 定义外键参数 db.ForeignKey('引用表名.引用字段名')
user_id = db.Column(db.Integer, db.ForeignKey('t_user.id'))
步骤
- 定义关系属性 relationship(“关联的类名”)
- 定义外键参数 db.ForeignKey(‘引用表名.引用字段名’)
使用关系属性
user1 = User.query.filter_by(name='张三').first()
for address in user1.addresses:
print(address.detail)
两条sql查询:
1、SELECT t_user.id AS t_user_id, t_user.name AS t_user_name
FROM t_user WHERE t_user.name = %s LIMIT %s;
2、SELECT t_adr.id AS t_adr_id, t_adr.detail AS t_adr_detail, t_adr.user_id AS t_adr_user_id FROM t_adr WHERE %s = t_adr.user_id
反向引用
定义
# 用户表 一 一个用户可以有多个地址
class User(db.Model):
__tablename__ = 't_user'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
addresses = db.relationship('Address', backref='user_info') # 设置backref参数 等效于 设置反向关系属性
# 地址表 多
class Address(db.Model):
__tablename__ = 't_adr'
id = db.Column(db.Integer, primary_key=True)
detail = db.Column(db.String(20))
user_id = db.Column(db.Integer, db.ForeignKey('t_user.id'))
# user_info = db.relationship('User') # 定义反向关系属性
步骤
- 同设置关系属性
- 设置backref参数 等效于设置反向关系属性
使用反向关系属性
# 查询到地址
adr = Address.query.filter(Address.detail == '中关村3号').first()
# 根据地址找人
print(adr.user_info.name) # 对一关系, 取出的是直接是模型对象
动态查询
定义
# 用户表 一 一个用户可以有多个地址
class User(db.Model):
__tablename__ = 't_user'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
# 开启动态查询后, 关系属性不再返回列表, 而是返回 AppenderBaseQuery对象
# AppenderBaseQuery对象 1> 具有BaseQuery的功能, 可以续接具体的查询条件 可以对结果集进行进一步的条件筛选 2> 保留了列表的特性, 仍然可以通过遍历和索引取值
addresses = db.relationship('Address', lazy='dynamic')
# 地址表 多
class Address(db.Model):
__tablename__ = 't_adr'
id = db.Column(db.Integer, primary_key=True)
detail = db.Column(db.String(20))
user_id = db.Column(db.Integer, db.ForeignKey('t_user.id'))
步骤
- 同设置关系属性
- 添加lazy=‘dynamic’
使用动态查询
# 先根据姓名查找用户主键
user1 = User.query.filter_by(name='张三').first()
# 使用关系属性获取关系数据 需求: 查询 姓名为"张三", 并且 地址以 "中关村" 开头的 地址信息
adrs = user1.addresses.filter(Address.detail.startswith('中关村')).all() # 对结果集进行进一步条件筛选
print(adrs[0].detail)
# for address in user1.addresses: # 遍历取值
# print(address.detail)
# print(user1.addresses[0].detail) # 索引取值