SQLAlchemy: Rapport de la table avec une clé primaire composite

J'ai un ensemble de tableaux qui ressemblent à:

workflows = Table('workflows', Base.metadata,
                  Column('id', Integer, primary_key=True),
                 )

actions = Table('actions', Base.metadata,
                Column('name', String, primary_key=True),
                Column('workflow_id', Integer, ForeignKey(workflows.c.id), primary_key=True),
               )

action_dependencies = Table('action_dependencies', Base.metadata,
                            Column('workflow_id', Integer, ForeignKey(workflows.c.id), primary_key=True),
                            Column('parent_action', String, ForeignKey(actions.c.name), primary_key=True),
                            Column('child_action', String, ForeignKey(actions.c.name), primary_key=True),
                           )

Mon ORM classes ressembler à:

class Workflow(Base):
    __table__ = workflows

    actions = relationship("Action", order_by="Action.name", backref="workflow")


class Action(Base):
    __table__ = actions

    children = relationship("Action",
                            secondary=action_dependencies,
                            primaryjoin=actions.c.name == action_dependencies.c.parent_action,
                            secondaryjoin=actions.c.name == action_dependencies.c.child_action,
                            backref="parents"
                           )

Donc, dans mon système, chaque action est identifiée de manière unique par la combinaison d'un flux de travail id et son nom. J'aimerais que chaque action ont parents et children attribut qui désigne son parent et de l'enfant actions. Chaque action peut avoir plusieurs parents et les enfants.

Le problème survient lorsque j'ai une fonction telle que :

def set_parents(session, workflow_id, action_name, parents):
    action = session.query(db.Action).filter(db.Action.workflow_id == workflow.id).filter(db.Action.name == action_name).one()

    for parent_name in parents:
        parent = session.query(db.Action).filter(db.Action.workflow_id == workflow.id).filter(db.Action.name == parent_name).one()
        action.parents.append(parent)

    session.commit()

J'obtiens une erreur comme:

IntegrityError: (IntegrityError) action_dependencies.workflow_id may not be NULL u'INSERT INTO action_dependencies (parent_action, child_action) VALUES (?, ?)' (u'directory_creator', u'packing')

Comment puis-je obtenir la relation pour définir la workflow_id correctement?

Pourquoi avez-vous besoin d'avoir workflow_id dans le action_dependencies table?
Parce que la clé primaire pour une action est un composite de son nom et workflow_id. Si le workflow_id n'était pas dans action_dependencies, il n'y aurait aucun moyen de savoir de quel flux de travail les actions de la dépendance faisait allusion.
Bon point bon point. laissez-moi réfléchir...
Veuillez noter que votre parents/children les relations devraient également inclure la workflow_id dans le primaryjoin et secondary conditions, sinon vous allez obtenir ces pour tous les worklows.

OriginalL'auteur Kamil Kisiel | 2012-05-09