2014-11-20 60 views
2

我想从组合键中删除表中的行。如何使用SQLAlchemy构造“DELETE WHERE EXISTS IN”?

我需要构造形式的查询:

DELETE FROM t WHERE EXISTS (c1, c2, c3) IN (subquery) 

我怎样才能做到这一点SQLAlchemy的?

这是一个例子,它有一个记录每个用户每个游戏多个分数的表格。我想删除的最低得分在每场比赛的用户参与了每一个用户

from sqlalchemy import Table, Column, MetaData, String, Integer 


metadata = MetaData() 
t = Table('scores', metadata, 
      Column('game',String), 
      Column('user',String), 
      Column('score',Integer)) 

的数据可能是这样的:

game  user score 
g1  u1  44 
g1  u1  33 
g1  u1  2  (delete this) 
g2  u1  55 
g2  u1  1  (and this) 

我想删除(g1,u1,2)(g2, u1,1)

这里是我的尝试至今使用的SQLAlchemy:

from sqlalchemy import delete, select, func, exists, tuple_ 

selector_tuple = tuple_(t.c.game, t.c.user, t.c.score) 
low_score_subquery = select([t.c.game, t.c.user, func.min(t.c.score)])\ 
         .group_by(t.c.game, t.c.user) 
in_clause = selector_tuple.in_(low_score_subquery) 
print "lowscores = ", low_score_subquery # prints expected SQL 
print "****" 
print "in_clause = ", in_clause # prints expected SQL 

而我得到​​和low_score_subquery预期的SQL,删除查询(下)是不正确的。我试过以下的变化,但都与坏的结果:

>>> delete_query = delete(t, exists([t.c.game, t.c.user, t.c.score], 
...         low_score_subquery)) 
>>> print delete_query # PRODUCES INVALID SQL 
DELETE FROM scores WHERE EXISTS (SELECT scores."game", scores."user", scores.score 
FROM (SELECT scores."game" AS "game", scores."user" AS "user", min(scores.score) AS min_1 
FROM scores GROUP BY scores."game", scores."user") 
WHERE (SELECT scores."game", scores."user", min(scores.score) AS min_1 
FROM scores GROUP BY scores."game", scores."user")) 

我已经试过exists(in_clause)exists([], in_clause)in_clause.exists()但这些都会导致异常。

回答

1

你真的需要存在吗?这不是你想要的吗?

>>> delete_query = delete(t, in_clause) 
>>> print(delete_query) 
DELETE FROM scores WHERE (scores.game, scores."user", scores.score) IN (SELECT scores.game, scores."user", min(scores.score) AS min_1 
FROM scores GROUP BY scores.game, scores."user")