2010-12-21 57 views
2

我是Python新手,還有SQL Alchemy,但不是基礎開發和數據庫概念。我知道我想要做什麼以及如何手動完成,但我試圖瞭解ORM的工作原理。在sqlalchemy中需要關於連接的幫助

我有兩個表,圖像和關鍵字。 Images表包含一個id列,它是主鍵,還有一些其他元數據。關鍵字表只包含一個id列(圖像的外鍵)和一個關鍵字列。我試圖正確地聲明這種關係使用聲明性語法,我認爲我已經正確地做了。

Base = declarative_base() 

class Keyword(Base): 
    __tablename__ = 'Keywords' 
    __table_args__ = {'mysql_engine' : 'InnoDB'} 

    id = Column(Integer, ForeignKey('Images.id', ondelete='CASCADE'), 
      primary_key=True) 
    keyword = Column(String(32), primary_key=True) 

class Image(Base): 
    __tablename__ = 'Images' 
    __table_args__ = {'mysql_engine' : 'InnoDB'} 

    id = Column(Integer, primary_key=True, autoincrement=True) 
    name = Column(String(256), nullable=False) 
    keywords = relationship(Keyword, backref='image') 

這代表了多對多的關係。一個圖像可以有很多關鍵字,一個關鍵字可以與許多圖像相關聯。

我想做一個關鍵字搜索我的圖片。我試過以下,沒有運氣。

從概念上講,這本來不錯,但我明白爲什麼它不起作用。

image = session.query(Image).filter(Image.keywords.contains('boy')) 

我不斷收到有關沒有外鍵關係的錯誤,這似乎對我來說很清楚。我看到了一些關於確保我獲得正確的「加入」的信息,而且我正在使用'from sqlalchemy.orm import join',但仍然沒有運氣。

image = session.query(Image).select_from(join(Image, Keyword)).\ 
     filter(Keyword.keyword == 'boy') 

我所添加的各種聯接子句來查詢,以幫助它一起,但據我所知,我不應該這樣做。

image = session.query(Image).select_from(join(Image, Keyword, 
    Image.id==Keyword.id)).filter(Keyword.keyword == 'boy') 

因此,最後我切換策略,並嘗試查詢關鍵字,然後使用反向引用。但是,當我嘗試使用遍歷結果的'.images'時,出現'image'屬性不存在的錯誤,即使我已將其聲明爲backref。

result = session.query(Keyword).filter(Keyword.keyword == 'boy').all() 

我希望能夠在一組關鍵字上查詢一組唯一的圖像匹配。我只是無法猜測我的語法,我花了數天的時間閱讀SQL Alchemy文檔,試圖自行完成這些工作。

我非常感謝任何能指出我失蹤的人。

回答

1

看來我仍然收到錯誤的連接版本,甚至在sqlalchemy.orm下導入了一個。我這樣做是爲了解決該問題:

from sqlalchemy.orm.util import join as join_ 

image = session.query(Image).select_from(join_(Image, Keyword)).\ 
    filter(Keyword.keyword == 'boy') 

那真的是「最正確」的解決方案,還是我失去了Python中的一些細微差別?由於我還在學習,所以我想按照經驗豐富的人的建議,以「最正確」的方式做事。謝謝。

+0

'join_`不是必須的,因爲當選擇`Keyword`實體時,根據爲`image`屬性定義的關係,相關的`Image`實體與它一起被檢索。我試過這個,它的工作原理是:`[k.image.name for k in session.query(Keyword).filter_by(keyword ='boy')。all()]` – scoffey 2010-12-21 20:28:54