2014-01-25 3 views
3

상위 테이블과 하위 테이블의 두 테이블이 있습니다. 하위에 부모가없는 경우 부모를 만들 수있는 이벤트 리스너 ("트리거")를 만들고 싶습니다. 상위 레코드를 만들 수있는 SQLAlchemy에서 이벤트 리스너를 만들 수 있습니까?

내가 어떻게 뭘하려 :

class parent(db.Model): 
    __tablename__ = 'parent' 
    id = db.Column(db.Integer, primary_key=True) 
    children = db.relationship("child", backref="parent", 
           cascade="all, delete-orphan", 
           passive_deletes=True) 


class child(db.Model): 
    __tablename__ = 'child' 
    id = db.Column(db.Integer, primary_key=True) 
    parent_id = db.Column(db.Integer, 
          db.ForeignKey('parent.id', ondelete='CASCADE'), 
          nullable=False) 


def create_parent(mapper, connection, target): 
    if not(target.parent): 
     target.parent = parent() 

event.listen(child, 'before_insert', create_parent)  

테스트 :

c = child() 
db.session.add(c) 
db.session.commit() 

하고있어 경고 및 오류 다음

C:\Python27\x\lib\site-packages\sqlalchemy\orm\unitofwork.py:79: SAWarning: Usage of the 'related attribute set' operation is not currently supported within the execution stage of the flush process. Results may not be consistent. Consider using alternative event listeners or connection-level operations instead. 
    sess._flush_warning("related attribute set") 

C:\Python27\x\lib\site-packages\sqlalchemy\orm\unitofwork.py:37: SAWarning: Usage of the 'collection append' operation is not currently supported within the execution stage of the flush process. Results may not be consistent. Consider using alternative event listeners or connection-level operations instead. 
    sess._flush_warning("collection append") 

sqlalchemy.exc.IntegrityError: (IntegrityError) null value in column "parent_id" violates not-null constraint 
DETAIL: Failing row contains (1, null). 
'INSERT INTO child (parent_id) VALUES (%(parent_id)s) RETURNING child.id' {'parent_id': None} 

내가 문서에서 발견되는이 없습니다 before_insert 이벤트에서 before_flush를 사용하여 구현할 수 있지만 그 작업을 수행하는 방법은 없습니다.

답변

2

그동안 나는이 문제를 해결할 방법을 찾았습니다.

from sqlalchemy.orm.session import Session as SessionBase 

def before_flush(session, flush_context, instances): 
    children = [c for c in session.new if isinstance(c, child)] 
    for c in children: 
     if not (c.parent): 
      c.parent = parent() 

event.listen(SessionBase, "before_flush", before_flush) 

누군가이 시나리오를 처리하는 적절한 방법이 아니라면 의견을 보내 주시면 감사하겠습니다.

관련 문제