2016-07-13 10 views
1

TLDR;問題は継承の構築にありました。私は宣言的なAPIを使用せずに作成する方法がわかりませんでした。サブクラスのインスタンスをSQLAlchemy関係に配置する

私はDeploymentJobのようなサブクラスによってさらに絞り込まれる一般的なモデルJobを作った。各Jobは、複数のActionsで構成されています。このJob<->Actionの関係を定義すると、サブクラスのインスタンスJobでは使用できません。私はDevelopmentJobを期待

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() 

Jobインスタンスとして受け入れられているが、この関連付けは行われません。

AssertionError: Attribute 'job' on class '<class '__main__.Action'>' doesn't handle objects of type '<class '__main__.DeploymentJob'>' 

答えて

0

問題がMapperがに提供JobのマッパーオブジェクトまでJobの子としてDeploymentJobをカウントされませんですマッパーオブジェクトDeploymentJobinherit引数として指定します。したがって、この作品:

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') 
関連する問題