Flask SQLAlchemy多表关联查询失败,求正确实现方案
修正模型并实现三表关联查询
你的模型存在几个关键问题,导致关联查询失败:
Employeeproject的project_id未设置外键关联Project表,SQLAlchemy无法识别两表的关联关系Employeeproject的__init__方法中employee_id参数类型定义为str,但Employee.id是Integer类型,类型不匹配会导致数据插入和关联出错- 模型间的
relationship定义不完整,缺少反向引用,不利于ORM层面的关联访问
修正后的模型代码
class Employee(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True) # 添加backref,方便从Employeeproject反向关联Employee employeeprojects = db.relationship("Employeeproject", backref="employee", lazy=True) def __init__(self, name: str): self.name = name class Employeeproject(db.Model): id = db.Column(db.Integer, primary_key=True) employee_id = db.Column(db.Integer, db.ForeignKey("employee.id"), nullable=False) # 补充外键关联Project表 project_id = db.Column(db.Integer, db.ForeignKey("project.id"), nullable=False) # 添加backref,方便从Project反向关联Employeeproject project = db.relationship("Project", backref="employeeprojects", lazy=True) # 修正employee_id参数类型为int def __init__(self, employee_id: int, project_id: int): self.employee_id = employee_id self.project_id = project_id class Project(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True) description = db.Column(db.String(300)) # 移除description的unique约束,避免同一个描述无法用于多个项目 def __init__(self, name: str, description: str): self.name = name self.description = description
实现三表关联查询的几种方式
方式1:利用ORM关系直接访问(最简便)
因为已经定义了完整的relationship,你可以直接通过对象属性访问关联数据:
# 获取第一个员工 employee = Employee.query.first() # 遍历该员工的所有关联项目 for emp_proj in employee.employeeprojects: print(f"员工{employee.name}参与项目:{emp_proj.project.name},描述:{emp_proj.project.description}")
方式2:使用join进行三表查询
如果你需要通过SQL join的方式获取关联数据,可以这样写:
# 查询所有员工及其关联的项目信息 results = db.session.query(Employee, Project)\ .join(Employeeproject, Employee.id == Employeeproject.employee_id)\ .join(Project, Employeeproject.project_id == Project.id)\ .all() # 遍历结果 for employee, project in results: print(f"员工:{employee.name},项目:{project.name}") # 如果只需要特定字段,比如员工姓名和项目名称 specific_results = db.session.query(Employee.name, Project.name)\ .join(Employeeproject)\ .join(Project)\ .all()
方式3:添加筛选条件的关联查询
比如查询某个员工参与的所有项目:
target_employee_name = "张三" projects = db.session.query(Project)\ .join(Employeeproject)\ .join(Employee)\ .filter(Employee.name == target_employee_name)\ .all() for project in projects: print(f"{target_employee_name}参与的项目:{project.name}")
内容的提问来源于stack exchange,提问作者Codernew
相关产品推荐
相关产品推荐

