【发布时间】:2018-02-11 21:10:21
【问题描述】:
我正在使用 sqlalchemy 编写查询,但我觉得我在做的事情不是应该做的:我得到的查询太复杂了,所以我认为这不是应该的方式使用数据库/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 中的所有元素,使得 B 中引用 A 的行数小于某个数量,假设是 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,并且这些用户不是从以前的查询中选择的。我不知道如何选择那些。
我的操作正确吗?具体来说,我想我应该使用多对多关系,但我想我会把这个编辑放在软件的下一次重构中。
【问题讨论】:
-
哼..也许只是一个选择,而“不在”选择可能是解决方案......
标签: mysql orm sqlalchemy