我自己熟悉 sqlalchemy。我有一个 mysql 查询如下:
SELECT COUNT( * ) AS total, SUM( IF(sub = 'N', 1, 0 ) ) AS NotSubscribed, SUM( IF( subscription = 'A', 1, 0 ) ) AS 12Month, SUM( IF( subscription = 'HY', 1, 0 ) ) AS 6Month, SUM( IF( subscription = 'M', 1, 0 ) ) AS 1Month
FROM accounts
WHERE userID IS NOT NULL
我正在尝试编写它的 sqlalchemy 版本。
users = Table('users',metadata,autoload=True)
userInfo = users.select([func.count(users.c.userID).label('Total'),
func.sum(users.c.sub == 'N').label('NotSubscribed'),
func.sum(users.c.sub == 'A').label('12Month'),
func.sum(users.c.sub =='HY').label('6Month'),
func.sum(users.c.sub == 'M').label('1Month')]).where(users.c.userID != None).execute()
我最终遇到了以下错误:
sqlalchemy.exc.ArgumentError: SQL expression object or string expected
谁能帮我看看哪里出错了。如果没有,请告诉我除了文档之外是否还有关于 sqlalchemy 的任何好的教程。
谢谢
请您参考如下方法:
sum 是您代码中的问题。要使其工作,您需要组合 sum 和 case。下面显示了两种使用 case 的方法(选一个你比较喜欢的):
qry = select([
func.count(users.c.userID).label("Total"),
func.sum(case(value=users.c.sub, whens={'N': 1}, else_=0)).label("NotSubscribed"),
func.sum(case(value=users.c.sub, whens={'A': 1}, else_=0)).label("12Month"),
func.sum(case([(users.c.sub == 'HY', 1)], else_=0)).label("6Month"),
func.sum(case([(users.c.sub == 'M', 1)], else_=0)).label("1Month"),
],
).where(users.c.userID != None)
res = engine.execute(qry)
print res.keys() # column names
print res.fetchone() # values
不过,我确实会考虑 Martijn 的建议,相应的 SA 表达式为:
qry = select([users.c.sub, func.count(users.c.userID)]).where(users.c.userID != None).group_by(users.c.sub)
res = engine.execute(qry)
rows = res.fetchall()
rows.append(('Total', sum(_r[1] for _r in rows))) # add Total
for row in rows:
print row
