2015-11-05 117 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