将多对多关系中的相关属性映射到它们自己的 'virtual' 列
Mapping related attributes in a many to many relationship to their own 'virtual' columns
我有两个多对多相关的 table,想了解如何将相关 table 的特定值映射为主题 table 的属性。
这是我使用 column_property 和关联 table:
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)
此数据的一位消费者要求 table A 应提供多个列(column_property/hybrid_property/plain_descriptor/something 否则?)包含来自关联 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 table 记录的名称属性(或 None 如果没有第一个/第二个相关记录)在 B.category 上匹配,类似地 A.z 应该包含第一个相关 B table 记录的名称属性。 A.x & A.z 大致做了他们应该做的,但我不知道如何将 A.y 映射到第二个相关 B 记录的名称属性。
这甚至是尝试建模的有用方法吗?我已经定义了 A.bees 关系 - 我可以利用它来填充 A.x、A.y 和 A.z 列吗?
我觉得我表达的不是很清楚,如果这没有意义,请随时要求澄清...谢谢!
事实证明它真的没有那么难(甚至真的是一个 sqlalchemy 问题!)。问题中的方法是完全有效的,只需要 SQL 到 select 第二条记录到 'y' column_property。对于 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)
我有两个多对多相关的 table,想了解如何将相关 table 的特定值映射为主题 table 的属性。
这是我使用 column_property 和关联 table:
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)
此数据的一位消费者要求 table A 应提供多个列(column_property/hybrid_property/plain_descriptor/something 否则?)包含来自关联 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 table 记录的名称属性(或 None 如果没有第一个/第二个相关记录)在 B.category 上匹配,类似地 A.z 应该包含第一个相关 B table 记录的名称属性。 A.x & A.z 大致做了他们应该做的,但我不知道如何将 A.y 映射到第二个相关 B 记录的名称属性。
这甚至是尝试建模的有用方法吗?我已经定义了 A.bees 关系 - 我可以利用它来填充 A.x、A.y 和 A.z 列吗?
我觉得我表达的不是很清楚,如果这没有意义,请随时要求澄清...谢谢!
事实证明它真的没有那么难(甚至真的是一个 sqlalchemy 问题!)。问题中的方法是完全有效的,只需要 SQL 到 select 第二条记录到 'y' column_property。对于 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)