使用连接查询不会选择相关对象

时间:2015-05-10 11:23:34

标签: python flask sqlalchemy

我正在尝试将表STUDENT加入STUDY_PROGRAM。学生到STUDY_PROGRAM是一对多的关系。对简单自然连接的查询没有给出预期的结果。调试显示查询结果没有“程序”列。

(Pdb) print mystudents[0].program
*** AttributeError: 'Student' object has no attribute 'program'
def students():
    mystudentinfo = mydb.session.query(Student).join(StudyProgram)
    return render_template('administration/students.html', studentinfo = mystudentinfo)

class Student(mydb.Model):
    __tablename__ = 'STUDENT'
    study_no = mydb.Column(mydb.String(20), primary_key = True)
    std_first_name = mydb.Column(mydb.String(64))
    std_last_name = mydb.Column(mydb.String(64))
    std_birthdate = mydb.Column(mydb.Date())
    std_email = mydb.Column(mydb.String(62))
    std_password = mydb.Column(mydb.String())
    study_programs = mydb.relationship('StudyProgram', backref='student')
    project_apps = mydb.relationship('ProjectApp', backref='student')

class StudyProgram(mydb.Model):
    __tablename__ = 'STUDY_PROGRAM'
    study_no = mydb.Column(mydb.String(20), mydb.ForeignKey('STUDENT.study_no'), primary_key = True)
    program = mydb.Column(mydb.String(100), primary_key = True)
    degree_type = mydb.Column(mydb.String(8), primary_key = True)
    reg_date = mydb.Column(mydb.Date())
    status = mydb.Column(mydb.String(20))
    earned_ECTs = mydb.Column(mydb.Numeric(4, 1))
    reg_ECTs = mydb.Column(mydb.Numeric(3, 1))
    tot_ECTs = mydb.Column(mydb.Numeric(4, 1))
    graduation_date = mydb.Column(mydb.Date())

1 个答案:

答案 0 :(得分:1)

查询没有选择Program中的任何一个,因为SQLAlchemy将联接与选择分开处理。

可以使用查询loading strategy调用更改关系的options()。由于您未对StudyProgram进行任何过滤,因此您可以省略join并设置joinedload选项。

students = db.session.query(Student).options(db.joinedload('study_programs'))

现在study_programs关系将在主查询期间加载,而不是作为单独的查询加载。如果您确实需要加入过滤,则可以使用contains_eager选项。

要访问每个学生的课程,请使用该关系。例如:

for s in students:
    print(s.first_name)

    for p in s.study_programs:
        print(p.program)

    print()

如果你使用joinedload,除了第一个询问学生之外,这不会发出任何疑问。如果不这样做,关系的默认行为是在访问时发出SELECT,因此每个学生将产生一个查询。

您遇到特定错误的原因是您将关系属性命名为study_programs,而不是program