2013-07-02 55 views
6

我試着寫與SQLAlchemy的ORM下面的SQL查詢:複雜的查詢(子查詢,窗口功能)與SQLAlchemy的

SELECT * FROM 
    (SELECT *, row_number() OVER(w) 
    FROM (select distinct on (grandma_id, author_id) * from contents) as c 
    WINDOW w AS (PARTITION BY grandma_id ORDER BY RANDOM())) AS v1 
WHERE row_number <= 4; 

這是我迄今所做的:

s = Session() 

unique_users_contents = (s.query(Content).distinct(Content.grandma_id, 
                Content.author_id) 
         .subquery()) 

windowed_contents = (s.query(Content, 
          func.row_number() 
          .over(partition_by=Content.grandma_id, 
            order_by=func.random())) 
        .select_from(unique_users_contents)).subquery() 

contents = (s.query(Content).select_from(windowed_contents) 
      .filter(row_number >= 4)) ## how can I reference the row_number() value? 

result = contents 
for content in result: 
    print "%s\t%s\t%s" % (content.id, content.grandma_id, 
          content.author_id) 

正如你所看到的,它的建模非常多,但我不知道如何從外部查詢中引用row_number()子查詢的結果。我嘗試了一些類似於windowed_contents.c.row_number並在窗口func中添加label()調用,但它不起作用,在官方文檔或計算器中找不到任何類似的示例。

這是如何實現的?另外,你能否提出一個更好的方法來做這個查詢?

回答

13

windowed_contents.c.row_number針對label()是你如何做到這一點,對我的作品(注意select_entity_from()方法是在SQLA 0.8.2新將在這裏需要0.9與select_from()):

from sqlalchemy import * 
from sqlalchemy.orm import * 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 

class Content(Base): 
    __tablename__ = 'contents' 

    grandma_id = Column(Integer, primary_key=True) 
    author_id = Column(Integer, primary_key=True) 


s = Session() 

unique_users_contents = s.query(Content).distinct(
          Content.grandma_id, Content.author_id).\ 
          subquery('c') 

q = s.query(
     Content, 
     func.row_number().over(
       partition_by=Content.grandma_id, 
       order_by=func.random()).label("row_number") 
    ).select_entity_from(unique_users_contents).subquery() 

q = s.query(Content).select_entity_from(q).filter(q.c.row_number <= 4) 

print q 
+0

' func.row_number()。over(...'在0.5版本中不起作用,所以解決方法? – dumper

+5

0.5是在六年前發佈的,升級?否則爲文本格式,例如text(「ROW NUMBER OVER」)或類似可能是你最直接的路線。 – zzzeek