Sqlalchemy多对多关系

3

我有两个表,它们之间存在多对多关系:

class Association(db.Model):
    __tablename__ = 'association'
    club_id = db.Column(db.Integer, db.ForeignKey('clubs.id'), primary_key=True)
    student_id = db.Column(db.Integer, db.ForeignKey('students.id'), primary_key=True)
    joined_date = db.Column(db.String)
    assoc_student = db.relationship("Student")

class Club(db.Model):
    __tablename__ = 'clubs'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    location = db.Column(db.String)
    club_assoc = db.relationship("Association")

class Student(db.Model):
    __tablename__ = 'students'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    age = db.Column(db.String)
    gender = db.Column(db.String)

问题:

1) 这两个查询有什么区别?

students = db.session.query(Association).filter_by(club_id='1')
students = Association.query.filter_by(club_id='1')

它们似乎给出了相同的结果!

2) 我正在尝试获取特定年龄的学生列表,但是以下查询不起作用:

db.session.query(Association).filter_by(Association.club_id=='1', Association.assoc_student.age=='15')

但是我遇到了这个错误:

属性错误:关联.assoc_student 没有 'age' 属性,它既不是 'InstrumentedAttribute' 对象也不是 'Comparator' 对象

所以我使用了这个:

db.session.query(Student).join(Association).filter(Association.club_id=='1', Student.age=='15')

有没有不使用“join”而更好的方法?也许可以使用“backref”!

1个回答

1

1) 这两个查询有什么区别?

它们几乎做同样的事情。前者是使用 SQLAlchemyFlask 用于访问数据库的库)来查询对象的方式。

后者是查询由 Flask-SQLAlchemy 库添加的模型的便捷方式。它使您的查询更易读,并扩展了一些有用的方法。请查看 flask_sqlalchemy.BaseQuery 类的源代码,以查看这些方法:get_or_404()first_or_404()paginate()

通常,您应该使用后者来查询对象。

2) 我正在尝试获取具有特定年龄的学生列表,但以下查询不起作用。

这里有两件事:

  1. 请注意filter()filter_by()方法之间的区别。在您的示例中,您尝试使用SQL表达式而不是kwargs来使用filter_by(),这是不正确的。
  2. 当您使用filter()时,您无法指定关系上的列(例如Association.assoc_student.age)。唯一允许的格式是ModelName.column_name。这就是为什么它失败的原因。

有更好的方法吗?

您的第二种方法是完全正确且可用的。我认为没有更好的方法。或者,您可以使用下面的代码避免导入db(如果您在另一个文件中定义查询):

Student.query.join(Association).filter(Association.club_id == '1', Student.age == '15')

谢谢@yaroslav管理员。我不确定我的类的结构,我避免使用“backref”,因为我不确定是否需要它来访问学生的列。 - Aseel
你的类结构很好。如果你需要一个“backref”,你可以随时添加它。 - Yaroslav Admin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接