我正在尝试将表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())
答案 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
。