Python SQLalchemy在多对一关系上加入

Python SQLalchemy在多对一关系上加入,python,mysql,sqlalchemy,Python,Mysql,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', seco

当我试图使用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)
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
以及映射表:

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'.

它确实可以工作

我不知道您的
元数据
对象来自何处,但是如果您将映射表代码更改为使用
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()
来自sqlalchemy.engine导入创建引擎
从sqlalchemy.ext.declarative导入声明性基础
从sqlalchemy.orm导入关系
从sqlalchemy.orm.session导入sessionmaker
从sqlalchemy.sql.schema导入列、表、ForeignKey
从sqlalchemy.sql.sqltypes导入整数、字符串
Base=声明性_Base()
类别蛋白质(碱基):
__tablename_uu=‘蛋白质’
id=列(整数,主键=True)
gene_name=列(字符串(45))
光谱命中率光谱命中率=关系('SpectrumHit',secondary='spectrum\u protein\u map')
等级SpectrumHit(基本):
__tablename_uuuu='spectrum_hit'
id=列(整数,主键=True)
序列=列(字符串(60,u'latin1\u german1\u ci'),索引=True)
光谱蛋白质图谱=表(
“光谱蛋白质图谱”,Base.metadata,
列('spectrum\u hit\u id',外键('spectrum\u hit.id'),
列('protein_id',ForeignKey('protein.id'))
)
eng=create\u引擎(“mysql://”,echo=False,pool\u recycle=1800)
Base.metadata.create_all(英文)
session\u maker=sessionmaker(bind=eng,autocommit=False,autoflush=False)
session=session\u maker()
res=session.query(Protein.gene_name,SpectrumHit.sequence).join(SpectrumHit.query.all)()

我不知道您的
元数据
对象来自何处,但如果您将映射表代码更改为使用
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()
来自sqlalchemy.engine导入创建引擎
从sqlalchemy.ext.declarative导入声明性基础
从sqlalchemy.orm导入关系
从sqlalchemy.orm.session导入sessionmaker
从sqlalchemy.sql.schema导入列、表、ForeignKey
从sqlalchemy.sql.sqltypes导入整数、字符串
Base=声明性_Base()
类别蛋白质(碱基):
__tablename_uu=‘蛋白质’
id=列(整数,主键=True)
gene_name=列(字符串(45))
光谱命中率光谱命中率=关系('SpectrumHit',secondary='spectrum\u protein\u map')
等级SpectrumHit(基本):
__tablename_uuuu='spectrum_hit'
id=列(整数,主键=True)
序列=列(字符串(60,u'latin1\u german1\u ci'),索引=True)
光谱蛋白质图谱=表(
“光谱蛋白质图谱”,Base.metadata,
列('spectrum\u hit\u id',外键('spectrum\u hit.id'),
列('protein_id',ForeignKey('protein.id'))
)
eng=create\u引擎(“mysql://”,echo=False,pool\u recycle=1800)
Base.metadata.create_all(英文)
session\u maker=sessionmaker(bind=eng,autocommit=False,autoflush=False)
session=session\u maker()
res=session.query(Protein.gene_name,SpectrumHit.sequence).join(SpectrumHit.query.all)()

My metadata object在文件metadata=Base中全局声明。metadata我已经编辑了我的响应,以包含适用于我的整个脚本-你能发现任何主要差异吗?我通过将映射表显式添加到join query=query.join(t_spectrum\u protein\u map)中找到了解决方案,谢谢!)我的元数据对象在metadata=Base文件中全局声明。元数据我已经编辑了我的响应,以包含适用于我的整个脚本-你能发现任何主要差异吗?我通过将映射表显式添加到join query=query.join(t_spectrum\u protein\u map)中找到了解决方案。无论如何,谢谢!)