加入SQLAlchemy中的所有相关表

时间:2016-03-21 17:42:34

标签: python sqlite pandas sqlalchemy

我有一个实验协议表,其中包含许多其他表的外键(最突出的是它包含许多Incubation个条目)。结构看起来像这样,逐字:

class DNAExtractionProtocol(Base):
    __tablename__ = 'dna_extraction_protocols'
    id = Column(Integer, primary_key=True)
    code = Column(String, unique=True)
    name = Column(String)
    sample_mass = Column(Float)
    mass_unit_id = Column(String, ForeignKey('measurement_units.id'))
    mass_unit = relationship("MeasurementUnit", foreign_keys=[mass_unit_id])
    digestion_buffer_id = Column(String, ForeignKey("solutions.id"))
    digestion_buffer = relationship("Solution", foreign_keys=[digestion_buffer_id])
    digestion_buffer_volume = Column(Float)
    digestion_id = Column(Integer, ForeignKey("incubations.id"))
    digestion = relationship("Incubation", foreign_keys=[digestion_id])
    lysis_buffer_id = Column(String, ForeignKey("solutions.id"))
    lysis_buffer = relationship("Solution", foreign_keys=[lysis_buffer_id])
    lysis_buffer_volume = Column(Float)
    lysis_id = Column(Integer, ForeignKey("incubations.id"))
    lysis = relationship("Incubation", foreign_keys=[lysis_id])
    proteinase_id = Column(String, ForeignKey("solutions.id"))
    proteinase = relationship("Solution", foreign_keys=[proteinase_id])
    proteinase_volume = Column(Float)
    inactivation_id = Column(Integer, ForeignKey("incubations.id"))
    inactivation = relationship("Incubation", foreign_keys=[inactivation_id])
    cooling_id = Column(Integer, ForeignKey("incubations.id"))
    cooling = relationship("Incubation", foreign_keys=[cooling_id])
    centrifugation_id = Column(Integer, ForeignKey("incubations.id"))
    centrifugation = relationship("Incubation", foreign_keys=[centrifugation_id])

    volume_unit_id = Column(String, ForeignKey('measurement_units.id'))
    volume_unit = relationship("MeasurementUnit", foreign_keys=[volume_unit_id])

现在,鉴于唯一的code归因,我想获得一个Pandas数据框(或者更确切地说是一个系列),它允许我不仅选择{{1}中相应条目的任何属性}表,但也在相关表中。

我目前正在选择一个pandas数据框:

"dna_extraction_protocols"

但这只允许我选择相关键的ID。我可以选择sql_query = session.query(DNAExtractionProtocol).join(DNAExtractionProtocol.digestion_buffer).filter(DNAExtractionProtocol.code == code) for item in sql_query: pass mystring = str(sql_query) mydf = pd.read_sql_query(mystring,engine,params=[code]) print(mydf) - 但我还希望能够选择mydf["dna_extraction_protocols_mass_unit_id"],并在mydf["dna_extraction_protocols_mass_unit_long_name"]表格中提供以下可用密钥:

"measurement_units"

2 个答案:

答案 0 :(得分:1)

这些问题的经典答案是创建SQL VIEW。

视图就像动态虚拟表 - 在查询中使用视图名而不是表名,DBMS运行视图定义的查询以在视图上生成查询的行。因此,您可以在访问视图时看到基于表中数据的行,而不是在创建视图时。

您可以使用

等语句创建此视图
CREATE VIEW PROT_WITH_UNITS AS
  SELECT * FROM dna_extraction_protocols P
           JOIN measurement_units M
             ON P.volume_unit = M.id

这将为您提供包含两个表的所有列的视图,预先连接(我认为是)所需的外键。

如果定义错误,您可以像表一样删除视图,因此最终应该到达那里。

答案 1 :(得分:0)

我可能遇到的解决这个问题的最pythonic方法是基于the response to a related question。似乎可以使用SQLAlchemy的data.frame。仍然存在的一个警告是,对于要加入的每个级别的相关表,您需要为最低检查调用添加嵌套for循环。

这是一个加入的示例: *主表的所有相关表 *主表所有相关表格的所有相关表格:

introspect module

我必须添加一个hack来排除ID列,因为它们会导致首选命名方案的重复列名称 - 但如果更改了命名方案,也可以保留这些列。