You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask-SQLAlchemy反向迭代:如何按Piece而非Side遍历数据?

当然可以实现这个需求!不过首先得补充一下你的模型——目前的Side类里没有区分Front/Back的字段,这是实现需求的前提,因为我们需要明确每个Piece属于哪个类型的Side。


第一步:完善模型定义

给Side类添加一个side_type字段,用来标记是Front还是Back:

class Side(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    job_id = db.Column(db.Integer, db.ForeignKey('job.id'))
    side_type = db.Column(db.String(20), nullable=False)  # 新增字段,值为'Front'或'Back'
    pieces = db.relationship('Piece', backref='side', lazy='select')

第二步:实现需求的两种方式

方式一:用SQLAlchemy聚合查询(推荐,效率更高)

直接通过SQL分组聚合,一次性获取所有Job、Piece及其对应的Side类型:

from sqlalchemy import func, array_agg

# 执行聚合查询
job_piece_data = db.session.query(
    Job.name,
    Piece.name,
    func.array_agg(Side.side_type).label('side_list')
).join(Side, Job.id == Side.job_id)\
 .join(Piece, Side.id == Piece.side_id)\
 .group_by(Job.name, Piece.name)\
 .order_by(Job.name, Piece.name)\
 .all()

# 整理成目标格式
result = {}
for job_name, piece_name, side_list in job_piece_data:
    # 对Side列表排序,保持和示例一致的顺序
    sorted_sides = sorted(side_list)
    if job_name not in result:
        result[job_name] = {}
    result[job_name][piece_name] = sorted_sides

# 输出结果
for job, pieces in result.items():
    print(f"- {job}")
    for piece, sides in pieces.items():
        print(f"  - {piece}: {', '.join(sides)}")

方式二:Python层面遍历处理(更直观)

如果不想用SQL聚合,也可以先查询所有Job,再逐层遍历关联对象,在Python层面收集每个Piece的Side信息:

jobs = Job.query.all()
result = {}

for job in jobs:
    piece_map = {}
    # 遍历当前Job的所有Side
    for side in job.sides:
        # 遍历当前Side下的所有Piece
        for piece in side.pieces:
            if piece.name not in piece_map:
                piece_map[piece.name] = []
            # 去重添加Side类型
            if side.side_type not in piece_map[piece.name]:
                piece_map[piece.name].append(side.side_type)
    # 对每个Piece的Side列表排序
    for p_name in piece_map:
        piece_map[p_name].sort()
    result[job.name] = piece_map

# 输出结果
for job, pieces in result.items():
    print(f"- {job}")
    for piece, sides in pieces.items():
        print(f"  - {piece}: {', '.join(sides)}")

最终输出结果

两种方式都会得到你期望的结构:

- Job 1
  - Piece 1: Front, Back
  - Piece 2: Front
- Job 2
  - Piece 3: Front, Back
  - Piece 4: Front, Back

内容的提问来源于stack exchange,提问作者Ricardo Reis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:42:04