2013-06-06 2 views
0

대부분 SQLAlchemy에서 Client 모델을 가지고 있습니다. 주로 선언적입니다. 이 모델은 name 필드를 가지고 MetaphoneCode 모델과 다 대다 관계를 유지합니다. 코드는 다음과 같이 진행됩니다SQLAlchemy에서 다른 필드가 수정되었을 때 관계를 업데이트하는 방법

class MetaphoneCode(Base): 
    """Represents a metaphone code 
    """ 
    __tablename__ = 'mcodes' 
    id = Column(Integer, Sequence('mcodes_seq_id'), primary_key=True) 
    code = Column(String(20), index=True, nullable=False) 


client_mcode_assoc_table = Table(
    'client_mcodes', 
    Base.metadata, 
    Column('client_id', ForeignKey('clients.id')), 
    Column('mcode_id', ForeignKey('mcodes.id'))) 


class Client(Base): 
    __tablename__ = 'clients' 
    id = Column(Integer, Sequence('client_id_seq'), primary_key=True) 
    name = Column(Unicode(100), index=True) 
    mcodes = relationship('MetaphoneCode', secondary=client_mcode_assoc_table) 

을 이제 name 자체가 변경할 때 내가 client.name = "John Doe"을 수행 할 때 내가 코드와 관련된 메타 폰을 계산하고 싶습니다 있도록 메타 폰 코드는 내가 이러한 요구를 표현하고 싶습니다 변경해야하기 때문에 그 이름 (성과 이름)이 업데이트되어 mcodes 관계가 업데이트되었습니다.

업데이트 : 간단한 해결책을 찾았습니다. below; 그래서 내 질문은 "으로 명시되어 있습니다. ORM 속성 이벤트 시스템이 다른 속성의 변경에 대한 응답으로 속성을 업데이트하는 최상의 방법입니까?"

+0

InstrumentedAttribute를 통과하지 않으려면 왜해야하나요? – ScotchAndSoda

+0

@ScotchAndSoda InstrumentedAttributed를 피하고 싶지는 않습니다. 단지 하위 클래스를 만들어서 그것의'__set__' 메쏘드가 콜백을 호출 할 것입니다. 하지만 SQLAlchemy에는 InstrutementedAttribute를 해킹하여 실제적으로 동일한 '@ event.listens_for'가 이미 있으므로 실제로는 필요하지 않습니다. 세터 용 +1 – manu

답변

0

내가 사용하여 이벤트에 의해 그것을 관리해야 : 아직도

@event.listens_for(Client.name, 'set') 
def update_mcodes(target, value, oldvalue, initiator): 
    target.recalculate_mcodes(value) 

을이이 작업을 수행하려면 권장되는 방법은? @Xaqq에서 제안한 하이브리드 접근법을 읽고이 내용이 event 것보다 우수한 지 결정합니다.

+0

이벤트에 대해 알지 못했지만 하이브리드 속성보다 우수 할 수 있습니다. 물론 숙련 된 사용자가 우리에게 infos를 주면 좋을 것입니다 : D – Xaqq

0

아마도 getter 및 setter를 사용하면 문제를 해결할 수 있습니다. .

SqlAlchemy는 모델의 특성에 getter 및 setter를 추가하는 방법을 제공합니다. 나는 그들 자신을 사용한 적이 없다. http://docs.sqlalchemy.org/en/rel_0_8/orm/extensions/hybrid.html을 참조하십시오.

그러나 나는 그 세터 내부에서 비즈니스 로직 코드를 실행하는 것이 좋은지 알 수 없다. 아마 더 경험이 많은 사람이 우리에게 말할 것입니다.

+0

+1. – ScotchAndSoda

+0

@Xaqq, @ScotchAndSoda : 하이브리드 속성이 내 유스 케이스와 어떻게 일치하는지 실제로 알 수 없습니다. setter로'fullname'' @ hybrid_property'를 정의해야 할 것 같습니다. 그렇다면'name' 대신'fullname'을 설정하기 위해 모든 코드를 변경해야합니다. 아니면'name '컬럼을'_name'으로 변경 한 다음'name'을 하이브리드 속성으로 정의해야합니다. 어느 쪽도 옳은 것처럼 보이지 않습니다. – manu

+0

@manu 두 번째 방법은 하이브리드 속성을 사용하는 방법이라고 생각합니다. (이해할 수있는 한) – Xaqq

관련 문제