【问题标题】:Sqlalchemy many to many relationshipSqlalchemy 多对多关系
【发布时间】:2015-09-03 06:30:57
【问题描述】:

我有两个多对多关系表:

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')

但我收到此错误:

AttributeError:与 Association.assoc_student 关联的“InstrumentedAttribute”对象和“Comparator”对象都没有属性“age”

这就是我使用这个的原因:

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

没有“加入”有没有更好的方法来做到这一点?也许使用“backref”!?

【问题讨论】:

    标签: python-2.7 flask sqlalchemy


    【解决方案1】:

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

    他们做几乎相同的事情。前者是查询SQLAlchemy 提供的对象的方式(库Flask 用于访问数据库)。

    后者是查询Flask-SQLAlchemy库添加的模型的便捷方式。它使您的查询更具可读性 + 使用一些有用的方法扩展查询。查看flask_sqlalchemy.BaseQuery 类的源代码以查看它们:get_or_404()first_or_404()paginate()

    通常你想使用后一种方法来查询对象。

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

    这里有两件事:

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

    有没有更好的办法?

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

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

    【讨论】:

    • 谢谢@yaroslav 管理员。我不确定我的课程结构,我远离“backref”,因为我不确定是否需要它来访问学生的 culmns。
    • 你的类结构很好。如果您需要backref,您可以随时添加。
    猜你喜欢
    • 1970-01-01
    • 2021-06-26
    • 2019-06-22
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多