Python 在SQLAlchemy关系中放置子类实例

Python 在SQLAlchemy关系中放置子类实例,python,sqlalchemy,Python,Sqlalchemy,TLDR;问题在于继承构造,我不知道在没有声明性API的情况下如何构造继承 我创建了通用模型Job,它将通过DeploymentJob这样的子类进一步缩小范围。每个作业由几个操作组成。如果我定义了这个JobAction关系,我就不能在Job子类实例中使用它 from sqlalchemy import (Table, Binary, Column as C, String, Integer, ForeignKey, create_engine, M

TLDR;问题在于继承构造,我不知道在没有声明性API的情况下如何构造继承

我创建了通用模型
Job
,它将通过
DeploymentJob
这样的子类进一步缩小范围。每个
作业
由几个
操作组成
。如果我定义了这个
JobAction
关系,我就不能在
Job
子类实例中使用它

from sqlalchemy import (Table, Binary, Column as C, String, Integer,
                        ForeignKey, create_engine, MetaData)
from sqlalchemy.orm import (mapper, relationship, backref, scoped_session,
                            sessionmaker)


metadata = MetaData()
db_engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(bind=db_engine))

class Job(object):
    pass

class DeploymentJob(Job):
    def __init__(self, *args, **kwargs):
        super(DeploymentJob, self).__init__(*args, **kwargs)

class Action(object):
    def __init__(self, unit, job):
        self.unit = unit
        self.job = job

jobs = Table('jobs', metadata,
             C('id', Integer, primary_key=True),
             C('type', String, nullable=False)
)

deployment_jobs = Table('deployment_jobs', metadata,
                        C('id', ForeignKey('jobs.id'), primary_key=True)
)

actions = Table('actions', metadata,
                C('job_id', ForeignKey('jobs.id'), primary_key=True),
                C('unit', String, primary_key=True)
)

mapper(Job,
       jobs,
       polymorphic_on=jobs.c.type,
       properties = {
           'actions': relationship(Action, lazy='dynamic', uselist=True,
                                   backref=backref('job', uselist=False)),
    }
)

mapper(DeploymentJob, deployment_jobs, polymorphic_identity='deployment')

mapper(Action, actions)


metadata.create_all(bind=db_engine)
unit = 'second-machine'
job = DeploymentJob()
action = Action(unit, job)

print "action.job -> %s is job: %s" % (action.job, isinstance(action.job, Job))
# >> action.job -> <__main__.DeploymentJob object at 0x7fe> is job: True

db_session.add(action)
db_session.add(job)

db_session.commit()

问题是
Mapper
不会将
DeploymentJob
作为
Job
的子对象计算,直到
Job
的Mapper对象作为
inherit
参数提供给
DeploymentJob
的Mapper对象。所以这是可行的:

JobsMapping = mapper(Job,
       jobs,
       polymorphic_on=jobs.c.type,
       properties = {
           'actions': relationship(Action, lazy='dynamic', uselist=True,
                                   backref=backref('job', uselist=False)),
    }
)

mapper(DeploymentJob, deployment_jobs, inherits=JobsMapping, polymorphic_identity='deployment')
JobsMapping = mapper(Job,
       jobs,
       polymorphic_on=jobs.c.type,
       properties = {
           'actions': relationship(Action, lazy='dynamic', uselist=True,
                                   backref=backref('job', uselist=False)),
    }
)

mapper(DeploymentJob, deployment_jobs, inherits=JobsMapping, polymorphic_identity='deployment')