2017-09-03 72 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))