我正在用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,并且未从先前的查询中选择这些用户。我不知道如何选择那些。
我正在进行中吗?具体来说,我想我应该使用多对多的关系,但我想我会把这个编辑放在软件的下一个重要因素中。
答案 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))