$ sudo mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.33-0ubuntu0.22.04.2 (Ubuntu)
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
>>> str(User.query.filter_by(username='1'))
'SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email \nFROM user \nWHERE user.username = %s'
我们给出一些常用的过滤器:
方法名
说明
filter()
把过滤器添加到原查询上,返回一个新查询
filter_by()
把等值过滤器添加到原查询上,返回一个新查询
limit()
使用指定的值限制原查询返回的结果数量,返回一个新查询
offset()
偏移原查询返回的结果,返回一个新查询
order_by()
根据指定条件对原查询结果进行排序,返回一个新查询
group_by()
根据指定条件对原查询结果进行分组,返回一个新查询
下表列出了执行查询的其他方法
方法名
说明
all()
以列表形式返回查询的所有结果
first()
返回查询的第一个结果,如果没有结果,则返回 None
first_or_404()
返回查询的第一个结果,如果没有结果,则返回 404 错误响应
get()
返回指定主键对应的行,如果没有对应的行,则返回 None
get_or_404()
返回指定主键对应的行,如果没找到指定的主键,则返回 404 错误响应
count()
返回查询结果的数量
paginate()
返回一个 Paginate 对象,包含指定范围内的结果
关系
关系型数据库使用关系把不同表中的行联系起来, 这也正是它强大处之一.
角色到用户的一对多关系. 一个角色可属于多个用户, 而每个用户都只能有一个角色.
class Role(db.Model):
# ...
users = db.relationship('User', backref='role')
class User(db.Model):
# ...
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
关系使用 users 表中的外键连接两行, 添加到 User 模型中的 role_id 列被定义为外键, 就是这个外键建立起了关系.
db.relationship() 中的 backref 参数向 User 模型中添加一个 role 属性, 从而定义反向关系.
通过 User 实例的这个属性可以获取对应的 Role 模型对象, 而不用再通过 role_id 外键获取.
为什么要多此一举做外键关联啊? 我直接多设置一个字段, 查询的时候匹配一下不就完了.
在设计数据表的时候, 很多情况下, 表示一对多关系, 你都恨不得有一个 XX 类型的数组作为某一类型的字段. 外键关联干的事情类似于这种方式. 它能显著减少我们代码的复杂度.
例如, 在下面的例子中, 我们把 Staff 和 Role 进行了关联. 在我们写的 to_json 文件里, 我们想知道 staff 的角色, 只需要调用 self.role.name 即可! 不需要你再在 Role 表里查询, 可谓是方便许多.
class Role(db.Model):
__tablename__ = 'role'
id = db.Column(db.Integer, primary_key=True, info='Primary Key')
name = db.Column(db.String(255))
class Staff(db.Model):
__tablename__ = 'staff'
id = db.Column(db.Integer, primary_key=True, info='Primary Key')
name = db.Column(db.String(255), nullable=False)
description = db.Column(db.Text())
role_id = db.Column(db.ForeignKey('role.id'), nullable=False, index=True)
hyper_link = db.Column(db.String(255))
role = db.relationship('Role', primaryjoin='Staff.role_id == Role.id', backref='staffs')
def to_json(self):
json_post = {
'id' : self.id,
'name' : self.name,
'description' : self.description,
'role' : self.role.name,
'hyper_link' : self.hyper_link
}
return json_post
@api.route('/staff')
def staff_info():
staff = Staff.query.all()
return jsonify({'data' : [person.to_json() for person in staff]})
多数情况下, db.relationship() 都能自行找到关系中的外键, 但有时却无法确定哪一列是外键. 例如, 如果 User 模型中有两个或以上的列定义为 Role 模型的外键, SQLAlchemy 就不知道该使用哪一列. 如果无法确定外键, 就要为 db.relationship() 提供额外的参数.