使用sqlalchemy过滤联接关系

时间:2017-09-03 12:13:56

标签: mysql orm sqlalchemy

我正在用sqlalchemy编写一个查询,我觉得我正在做的事情不是因为它要做的事情:我得到的查询太复杂了所以我认为这不是应该的方式使用databases / orm。

这是我的架构的简化版本:

class User(Base):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    longs = db.relationship('Login', backref='users')

class Login(Base):
    __tablename__ = 'logins'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    browser = db.Column(db.String(64)

对于给定的状态,我希望A中的所有元素都使引用A的B中的行数小于某个数,让我们说5。

对于一个真实案例,想象一下: A是用户列表 B是登录列表:

我想拥有使用Firefox登录不到5次的所有用户的列表。这还包括从未登录过的用户!

在SQL / sqlalchemy中,我会这样做:

1)使用左连接选择没有登录的行

never_loggedin = session.query(User).join(Login,
Logins.user_id == User.id).\
        filter(Login.user_id == None)

2)选择使用Firefox登录并仅使用计数小于5的那些。

sub_query = session.query(Login).filter(Login.browser ==
browser).subquery() 
less_ex = session.query(User).outerjoin(sub_query,
sub_query.c.user_id ==
User.id).group_by(sub_query.c.user_id).having(func.count(User.id) <
repetition) 

3)现在我有了这个问题。可能有用户已登录但从未使用过Firefox,并且未从先前的查询中选择这些用户。我不知道如何选择那些。

我正在进行中吗?具体来说,我想我应该使用多对多的关系,但我想我会把这个编辑放在软件的下一个重要因素中。

1 个答案:

答案 0 :(得分:1)

  sub_query = session.query(Login.user_id).filter(Login.browser == browser).group_by(Login.user_id).having(func.count(Login.id) >= repetition).subquery()
  less = session.query(User).filter(~User.id.in_(sub_query))