简体   繁体   English

Sqlalchemy有很多很多关系

[英]Sqlalchemy many to many relationship

I have two tables in many to many relationship: 我有很多关系中的两个表:

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)

Questions: 问题:

1) What is the difference between these two queries? 1)这两个查询之间有什么区别?

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

They seem to give the same result! 他们似乎给出了同样的结果!

2) I'm trying to get a list of students with certain age but this following query doesn't work: 2)我正在尝试获取具有特定年龄的学生列表,但以下查询不起作用:

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

But I get this error: 但我得到这个错误:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Association.assoc_student has an attribute 'age' AttributeError:与Instru.assoc_student关联的'InstrumentedAttribute'对象和'Comparator'对象都没有属性'age'

That's why I'm using this one: 这就是我使用这个的原因:

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

Is there a better way to do this without "join"? 没有“加入”,有更好的方法吗? Maybe with using "backref"!? 也许使用“backref”!?

1) What is the difference between these two queries? 1)这两个查询之间有什么区别?

They do almost the same thing. 他们几乎做同样的事情。 Former is the way to query objects provided with SQLAlchemy (library Flask uses to access database). 前者是查询SQLAlchemy提供的对象的方法( Flask用于访问数据库的库)。

Latter is the convenient way to query models added by Flask-SQLAlchemy library. 后者是查询Flask-SQLAlchemy库添加的模型的便捷方式。 It makes your queries more readable + extends query with few useful methods. 它使您的查询更具可读性+使用一些有用的方法扩展查询。 Take a look at source of the flask_sqlalchemy.BaseQuery class to see them: get_or_404() , first_or_404() and paginate() . 看一下flask_sqlalchemy.BaseQuery类的来源,看看它们: get_or_404()first_or_404()paginate()

Usually you want to use latter method to query objects. 通常您希望使用后一种方法来查询对象。

2) I'm trying to get a list of students with certain age but this following query doesn't work. 2)我正在尝试获取具有特定年龄的学生列表,但以下查询不起作用。

There are two things here: 这里有两件事:

  1. Be aware about the difference between filter() and filter_by() methods. 请注意filter()filter_by()方法之间的区别。 In your example you try to use filter_by() with SQL expressions instead of kwargs , which is incorrect. 在您的示例中,您尝试将filter_by()与SQL表达式而不是kwargs ,这是不正确的。
  2. When you're using filter() you can't specify columns over a relationships (like Association.assoc_student.age ). 当您使用filter()您无法在关系上指定列(例如Association.assoc_student.age )。 The only allowed format is ModelName.column_name . 唯一允许的格式是ModelName.column_name That's why it fails. 这就是它失败的原因。

Is there a better way? 有没有更好的办法?

Your second approach is absolutely correct and fine to use. 你的第二种方法是绝对正确和使用的。 I don't think there is a better way to do it. 我不认为有更好的方法来做到这一点。 Alternatively you can use code below to avoid importing db (if you define query in another file): 或者,您可以使用下面的代码来避免导入db (如果您在另一个文件中定义查询):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM