多条语句优化为一条可以减少通信次数,提高效率。
# 多次执行
users_info = [User.query.get(userId).to_dict() for userId in userIds]
# 一次执行
users = [user.to_dict() for user in User.query.filter(User.id.in_(userIds)).all()]
但是有一个问题就是,原来我们是按照userIds列表顺序查询的,而这里我的查询的结果却是按id顺序查询的。这是因为mysql会自动按id顺序查询,这样查询效率会更高。
所以我们需要使用sqlalchemy的case参数指定排序方法,也可以同时使用多个case参数
from app import app
from model import User
from sqlalchemy import case
with app.app_context():
userIds = [100, 32, 45, 67, 200, 146]
order_by = {userIds[i]: i for i in range(len(userIds))}
print(User.query.filter(User.id.in_(userIds)).order_by(
case(value=User.id, whens=order_by)
).all())
# [<User 100>, <User 32>, <User 45>, <User 67>, <User 200>, <User 146>]
同样使用func.field也可以实现自定义排序,并且使用方法更为简单。
from sqlalchemy import func
with app.app_context():
userIds = [100, 32, 45, 67, 200, 146]
print(User.query.filter(User.id.in_(userIds)).order_by(
func.field(User.id, *userIds)
).all())
# [<User 100>, <User 32>, <User 45>, <User 67>, <User 200>, <User 146>]
当然我们也可以在python中进行排序
with app.app_context():
userIds = [100, 32, 45, 67, 200, 146]
users = User.query.filter(User.id.in_(userIds)).all()
temp = {user.id: user for user in users}
users = [temp[id] for id in userIds]
print(users)
# [<User 100>, <User 32>, <User 45>, <User 67>, <User 200>, <User 146>]