从SQLAlchemy继承加入表继承类

时间:2018-03-04 12:05:11

标签: python python-3.x orm sqlalchemy

Python 3.6和SQLAlchemy 1.2。

我有一个名为events的包,它将Match定义为Event的类型,并使用连接表继承将其与其他类型的Event区分开来。另一种类型的事件是Competition,所有事件都是一个或另一个:

class Event(Base):
    __tablename__ = 'tbl_events'
    event_id = Column(Integer, primary_key=True)
    event_type_id = Column(String(50))  # 0 is Match, 1 is Competition

    __mapper_args__ = {'polymorphic_on': event_type_id}

class Match(Event):
    __tablename__ = 'tbl_match_details'

    event_id = Column(Integer,
                      ForeignKey('tbl_events.event_id'),
                      primary_key=True)
    team_1 = Column(String(50))
    team_2 = Column(String(50))

    __mapper_args__ = {'polymorphic_identity': 0}

我在另一个包中使用Match来区分多种类型的Match并依赖于Match对象的attribs和方法从数据库中提取事件信息但是远离除此之外的数据库:

from events import Match

class BaseMatch(Match):
    # define common methods and attrs

class TennisMatch(BaseMatch):

    # do Tennis based stuff

class FootballMatch(BaseMatch):

    # do football based things

events.Match与从它继承的类之间的任何区别仅在此包中有效,并且此包不会以其他方式插入或更新数据库,只能从中读取。

我遇到的问题是尝试实例化从Match继承的任何类的实例会导致NULL值传递到event_type_id的查询中领域。这是查询的WHERE部分:

WHERE tbl_match_details.event_id = %s AND tbl_events.match_comp_id IN (NULL)

我不能简单地为每个类提供自己的多态标识符,因为这些标识符不会存在于数据库中。

我试过了:

class BaseMatch(Match):
    @declared_attr
    def __mapper_args__(cls):
        return {'polymorphic_identity': 0}

class TennisMatch(BaseMatch):
    # do tennis stuff

class FootballMatch(BaseMatch):
    # do footy stuff

但导入模块后,我收到警告:

SAWarning: Reassigning polymorphic association for identity 0 from <Mapper at 0x7f80197f0550; Match> to <Mapper at 0x7f80197a9fd0; BaseModel>: Check for duplicate use of 0 as value for polymorphic_identity.
SAWarning: Reassigning polymorphic association for identity 0 from <Mapper at 0x7f80197a9fd0; BaseModel> to <Mapper at 0x7f800dfdf940; TennisMatch>: Check for duplicate use of 0 as value for polymorphic_identity.

我从每个继承自Match的类中得到其中一个,当我尝试实例化任何匹配类型时,我得到一个与该多态id相关联的类型的实例。

我真的很感激在正确的方向上轻推!

感谢。

1 个答案:

答案 0 :(得分:0)

这是我为解决这个问题所做的工作 - 我不确定它是否正确#39;但它让我能够继续我正在做的事情,并帮助我了解更多内容。

我已经在我的赛事,比赛和比赛课程上创建了工厂方法,并在竞赛和比赛中创建了一个类属性,让我可以访问每个事件类型的event_type_id值:

$postedMidNight = strtotime('midnight '.date('y-m-d',$postedTime))+ 86400 ;
foreach ($tokens as $unit => $text) {
    if ($time < $unit)
        continue;
    $numberOfUnits = floor($time / $unit);

    if (time() > $postedMidNight) {
        return date('d.m.Y', $timestamp);
    } else {
        return $numberOfUnits . ' ' . $text . (($numberOfUnits > 1) ? 's' : '');
    }
}

这样,每当使用工厂方法实例化从Match或Competition继承的类时,多态标识将被强制转换为父类定义的标识,并且多态映射将该标识指向工厂所调用的类。在

对我来说显而易见的一个缺点是,只有在通过工厂方法实例化对象时,这才会起作用。在这种情况下很好,但可能不是全部。

非常感谢任何关于我如何解决这个问题的反馈以及任何指向更清洁解决方案的建议。

由于