Skip to main content
 首页 » 编程设计

python之mysql查询到sqlalchemy版本

2025年05月04日29kuangbin

我自己熟悉 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