2017-09-03 70 views
2

我正在用sqlalchemy写一个查询,我觉得我正在做的事情并非如此:我收到的查询太复杂了,所以我认为这是不是应该使用数据库/ orm的方式。过滤与sqlalchemy的连接关系

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

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,使得所有元素引用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)选择登录登录与火狐,并采取只有那些计数小于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,而且这些用户没有从之前的查询中选择。我不知道如何选择这些。

我正在继续吗?具体来说,我想我应该使用多对多的关系,但我想我会把这个编辑放在下一个软件的重新分解中。

+0

嗡嗡声..也许只是一个选择和“不在”选择可能是解决方案... – asdf

回答

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