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")