SQLAlchemy中有多个父母的多对多

时间:2013-08-19 03:45:23

标签: python sql sqlalchemy

我不确定标题是否正确所以让我举个例子

说我有TableATableB个班级,以及History班级。

History只是id, attribute, old value, new value

每个表与History有很多关系。

显然,我可以创建一个tablea_historytableb_history表来跟踪关系。

但是我将拥有5-10个TableA/B类型表和3-4个History类型表,因此可以添加相当多的简单关系表。这样可以吗? (在管理和效率方面?)似乎会增加很多额外的代码。

我也可以History定义id, table_name, attribute, old, new,但后来我不知道如何创建好的SQLAlchemy关系。

TL; DR

我想我问的是,将子表与多种(不同类)的父表关联起来的最佳方法是什么,这样我就不用担心幕后的东西,只使用不错的SQLalchemy关系。

1 个答案:

答案 0 :(得分:0)

所以这就是我决定的。我不确定它是否效率最高,但似乎应该是......请注意EventHistoryDeviceTableA/B。< / p>

您可以使用像here这样的Mixin轻松地将关系添加到所有表格中。然后,您可以修改relationship()的primaryjoin属性以按表过滤。示例代码:

class Event(Base):

    #tablename
    type = Column(Unicode(50), nullable=False, index=True)
    #foreign id
    table_id = Column(Integer, nullable=False, index=True)
    attr = Column(Unicode(50), nullable=False)
    old = Column(Unicode(50), nullable=False)
    new = Column(Unicode(50), nullable=False)

class MetadataMixin(object):
    @declared_attr
    def events(cls):
        joinstr = '{0}.id == foreign(Event.table_id) and Event.type == "{1}"'.format(cls.__name__, cls.__tablename__)
        return relationship('Event', primaryjoin=joinstr, backref=cls.__name__.lower())

现在我们可以使用它:

class Device(MetadataMixin, Base):
    pass

>>> d = Device()
>>> d.events
[]

在接受这个答案之前,我会暂时搁置这个问题,看看是否有人提出了更好的答案。