2015-11-05 220 views
1

我完全卡在嘗試使用SQLAlchemy加入一對多關係。 我的模型看起來是這樣的:SQLalchemy加入多對一的關係

class Protein(Base): 
    __tablename__ = 'protein' 

    protein_id = Column(Integer, primary_key=True) 
    gene_name = Column(String(45)) 

    spectrum_hit_spectrum_hits = relationship(u'SpectrumHit', secondary='spectrum_protein_map') 


class SpectrumHit(Base): 
    __tablename__ = 'spectrum_hit' 

    spectrum_hit_id = Column(Integer, primary_key=True)  
    sequence = Column(String(60, u'latin1_german1_ci'), index=True) 

和映射表:

t_spectrum_protein_map = Table(
    'spectrum_protein_map', metadata, 
    Column('spectrum_hit_spectrum_hit_id', ForeignKey(u'spectrum_hit.spectrum_hit_id'), nullable=False, index=True), 
    Column('protein_protein_id', ForeignKey(u'protein.protein_id'), nullable=False, index=True) 
) 

我的查詢是:

query = DBSession.query(Protein.gene_name, SpectrumHit.sequence) 
     query = query.join(SpectrumHit) 
     result = query.all() 

我也試了一下週圍的其他方法

query = DBSession.query(SpectrumHit.sequence, Protein.gene_name) 
     query = query.join(Protein) 
     result = query.all() 

如果有幫助,我也可以添加我的MySQL表。

我總是得到錯誤:

InvalidRequestError: Could not find a FROM clause to join from. Tried joining to <class 'ligando.models.Protein'>, but got: Can't find any foreign key relationships between 'spectrum_hit' and 'protein'. 

這就解釋了自己......

如果我嘗試做平原的MySQL這個查詢它看起來像這樣:

SELECT spectrum_hit.sequence, protein.gene_name 
From spectrum_hit 
join spectrum_protein_map on spectrum_hit.spectrum_hit_id = spectrum_protein_map.spectrum_hit_spectrum_hit_id 
join protein on protein.protein_id = spectrum_protein_map.protein_protein_id 

而且它的工作

回答

0

我不知道你的metadata對象來了,但如果你cha NGE映射表的代碼使用Base.metadata,你的代碼將工作:

from sqlalchemy.engine import create_engine 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import relationship 
from sqlalchemy.orm.session import sessionmaker 
from sqlalchemy.sql.schema import Column, Table, ForeignKey 
from sqlalchemy.sql.sqltypes import Integer, String 

Base = declarative_base() 

class Protein(Base): 
    __tablename__ = 'protein' 

    id = Column(Integer, primary_key=True) 
    gene_name = Column(String(45)) 

    spectrum_hit_spectrum_hits = relationship('SpectrumHit', secondary='spectrum_protein_map') 


class SpectrumHit(Base): 
    __tablename__ = 'spectrum_hit' 

    id = Column(Integer, primary_key=True) 
    sequence = Column(String(60, u'latin1_german1_ci'), index=True) 



spectrum_protein_map = Table(
    'spectrum_protein_map', Base.metadata, 
    Column('spectrum_hit_id', ForeignKey('spectrum_hit.id')), 
    Column('protein_id', ForeignKey('protein.id')) 
) 

eng = create_engine("mysql://<your connection string>", echo=False, pool_recycle=1800) 
Base.metadata.create_all(eng) 
session_maker = sessionmaker(bind=eng, autocommit=False,autoflush=False) 
session = session_maker() 

res = session.query(Protein.gene_name, SpectrumHit.sequence).join(SpectrumHit).query.all() 
+0

我的元數據對象是全球範圍內聲明的文件中 元= Base.metadata – Linus

+0

我已經編輯我的反應,包括整個腳本作品對我來說 - 你能發現任何主要的區別嗎? – wilfo

+0

我通過明確地將映射表添加到連接中找到了解決方案 query = query.join(t_spectrum_protein_map) 無論如何,謝謝! :) – Linus