将多对多关系中的相关属性映射到其自己的'virtual'列



我有两个多对多的相关表,想了解如何将相关表的特定值映射为主题表的属性。

以下是我使用column_perty和关联表得到的内容:

class Assoc_Table(Base):
__tablename__ = 'assoc_table'
__table_args__ =  {'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}
a_id = Column(Unicode(255), ForeignKey('a.id'), primary_key=True)
b_id = Column(Integer, ForeignKey('b.id'), primary_key=True)

class A(Base):
__tablename__ = 'a'
__table_args__ = {'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}
id   = Column(Unicode(255), primary_key=True)
bees = relationship("B", secondary="assoc_table", back_populates="as")

class B(Base):
__tablename__ = 'b'
__table_args__ = {'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}
id       = Column(Integer, primary_key=True)
as       = relationship("A", secondary="assoc_table", back_populates="bees")
name     = Column(Unicode(255))
category = Column(Integer)

该数据的使用者之一要求表A应提供几个列(column_perty/hybrid_property/plane_descriptor/其他什么?(,其中包含相关A.bees集合中几个不同项目的名称属性。类似这样的东西:


class A(Base):
__tablename__ = 'a'
__table_args__ = {'mysql_engine': 'InnoDB', 'mysql_charset': 'utf8'}
id   = Column(Unicode(255), primary_key=True)
bees = relationship("B", secondary="assoc_table", back_populates="as")
x    = column_property(select([B.name]).where(and_(Assoc_Table.a_id==id, Assoc_Table.b_id==B.id, B.category==1)).limit(1), deferred=True)
y    = column_property(select([B.name]).where(and_(Assoc_Table.a_id==id, Assoc_Table.b_id==B.id, B.category==1)).limit(2), deferred=True)
z    = column_property(select([B.name]).where(and_(Assoc_Table.a_id==id, Assoc_Table.b_id==B.id, B.category==2)).limit(1), deferred=True)

(如果语法有点不稳定,请道歉,但这与ATM实现的语法很接近(。

映射属性A.x&A.y旨在保持第一&第二个相关的B表记录(如果没有第1/2个相关记录,则为"无"(在B.category上匹配,类似地,a.z应保持第一个相关B表记录的name属性。A.x&A.z大致做了他们应该做的事情,但我不知道如何将A.y映射到第二个相关B记录的name属性。

这甚至是一种尝试对此进行建模的有用方法吗?我已经定义了A.bees关系——我可以利用它来填充A.x、A.y&而是A.z列?

我觉得我没有很清楚地表达这一点,如果这没有意义,请随时要求澄清。。。谢谢

事实证明,这并没有那么难(甚至真的是一个sqlalchemy问题!(。问题中的方法是完全有效的,只需要SQL将第二条记录选择到"y"列_属性中。对于MySQL(这个问题的目标数据库(,以下语法实现了目标:

x    = column_property(select([B.name]).where(and_(Assoc_Table.a_id==id, Assoc_Table.b_id==B.id, B.category==1)).limit(1), deferred=True)
y    = column_property(select([B.name]).where(and_(Assoc_Table.a_id==id, Assoc_Table.b_id==B.id, B.category==1)).offset(1).limit(1), deferred=True)
z    = column_property(select([B.name]).where(and_(Assoc_Table.a_id==id, Assoc_Table.b_id==B.id, B.category==2)).limit(1), deferred=True)

最新更新