2011-05-06 65 views
6

我試圖執行一個查詢,該查詢可以在bmarks和帶有bmarks_tags輔助表的標記之間進行多對多關係。該查詢涉及幾個子查詢,我需要DISTINCT一列。我後來想通過DISTINCT'd ID將它加入到另一個表中。sqlalchemy:在過濾器或子句元素中引用label()'d列

我已經試過了幾個方法,這似乎最接近:

tagid = alias(Tag.tid.distinct()) 
test = select([bmarks_tags.c.bmark_id], 
       from_obj=[bmarks_tags.join(DBSession.query(tagid.label('tagid'))), 
         bmarks_tags.c.tag_id == tagid]) 

return DBSession.execute(qry) 

但我得到一個錯誤:

⇝ AttributeError: '_UnaryExpression' object has no attribute 'named_with_column' 

有誰知道我怎麼能進行跨bmarks_tags的加入。 tag_id和Tag.tid.distinct()的結果?

感謝

模式:

# this is the secondary table that ties bmarks to tags 
bmarks_tags = Table('bmark_tags', Base.metadata, 
    Column('bmark_id', Integer, ForeignKey('bmarks.bid'), primary_key=True), 
    Column('tag_id', Integer, ForeignKey('tags.tid'), primary_key=True) 
) 

class Tag(Base): 
    """Bookmarks can have many many tags""" 
    __tablename__ = "tags" 

    tid = Column(Integer, autoincrement=True, primary_key=True) 
    name = Column(Unicode(255), unique=True) 
+0

請張貼您的架構,以便我們可以重現它。 – letitbee 2011-05-07 09:28:00

+0

SELECT表達式看起來相當混亂。你有實際的SQL嗎? – sayap 2011-05-10 07:48:12

回答

4

像這樣的東西應該工作:

t = DBSession.query(Tag.tid.distinct().label('tid')).subquery('t') 
test = select([bmarks_tags.c.bmark_id], bmarks_tags.c.tag_id == t.c.tid) 
return DBSession.execute(test) 
+0

我認爲這會奏效。我最終只是以不同的方式討論查詢。我想我錯過了.subquery()來幫助我得到一些知道.c.tid是什麼的東西。別名等不允許該引用。如果有人想看到完整的工作實現/等你可以在這裏查看:http://goo.gl/GV9x7 – Rick 2011-05-23 00:56:55

+2

感謝你。這是我解決一個不同問題的一個重要提示,即在稍後的某個條款中獲得一個標籤列。解決方案是提取標籤對象並在兩個地方引用它,例如,var_col = at.c ['X']。label('var_name')... query = select([at.c ['id' ],var_col],whereclause = var_col!= None) – 2013-01-28 23:09:49

1

這是很難告訴你要完成什麼,但既然你反正使用ORM (現在再也沒有太多理由選擇sa),那麼你應該先建立一個多對多的關係:

bmarks_tags = Table('bmark_tags', Base.metadata, 
    Column('bmark_id', Integer, ForeignKey('bmarks.bid'), primary_key=True), 
    Column('tag_id', Integer, ForeignKey('tags.tid'), primary_key=True) 
) 

class Tag(Base): 
    """Bookmarks can have many many tags""" 
    __tablename__ = "tags" 

    tid = Column(Integer, primary_key=True) 
    name = Column(Unicode(255), unique=True) 

class BMark(Base): 
    __tablename__ = 'bmarks' 
    bid = Column(Integer, primary_key=True) 
    tags = relation(Tag, secondary=bmarks_tags, backref="bmarks") 

然後讓你的查詢,並從那裏:

query = DBSession.query(BMark).join(BMark.tags) 

如果沒有,給我們你正試圖使SQLAlchemy的發射實際的SQL。