2016-04-11 5 views
1

У меня есть следующие основные модель SQLAlchemy с многим ко многие ссылки себя:SQLAlchemy самоссылающихся многих ко многим с дополнительными данными об ассоциации

class Organisation(Base): 
    __tablename__ = 'organisation' 

    name = Column(String(50)) 
    url = Column(String(128)) 
    associated = relationship(
         'Organisation', 
         secondary="organisation_map", 
         primaryjoin="Organisation.id==organisation_map.c.organisation_id", 
         secondaryjoin="Organisation.id==organisation_map.c.assoc_organisation_id", 
         backref="account_organisation" 

    ) 

В таблице ассоциации выглядит следующим образом:

class OrganisationMap(Base): 
    __tablename__ = 'organisation_map' 

    organisation_id = Column(Integer, ForeignKey('organisation.id')) 
    assoc_organisation_id = Column(Integer, ForeignKey('organisation.id')) 
    is_customer = Column(Boolean, default=False) 
    is_supplier = Column(Boolean, default=False) 

Таблица ассоциации содержит дополнительные данные, is_customer и is_supplier, которые я хочу получить от самой модели, например:

class Organisation(Base): 
    ... 

    def get_suppliers(self): 
     pass 

    def get_customers(self): 
     pass 

На данный момент у меня нет никакого способа получения такого списка без первого запроса на объединении таблицы, OrganisationMap, получая идентификаторов из «клиентов» или «поставщики», а затем запрашивая Organisation таблицу со списком идентификаторов.

Возможно ли это?

+0

См. [Этот вопрос] (http://stackoverflow.com/questions/7417906/sqlalchemy-manytomany-secondary-table-with-additional-fields). Самореферентная часть должна требовать только номинальных изменений конфигурации. – univerio

ответ

0

Он считает, что вы должны иметь возможность использовать события ORM для вставки и обновления ваших is_customer и is_supplier соответственно. I.e .:

@event.listens_for(OrganisationMap, 'after_insert') 
@event.listens_for(OrganisationMap, 'after_update') 
def update_organization_map(mapper, connection, target): 
    # query your db to fill this 2 fields accordingly 
    # you have the connection object 
    target.is_customer = query_to_fill_is_customer 
    target.is_supplier = query_to_fill_is_supplier 

Я не знаю, подходят ли события, которые я использовал в приведенном выше примере, для вас. Пожалуйста, прочитайте страницу события SQLAlchemy ORM для полного списка:

http://docs.sqlalchemy.org/en/latest/orm/events.html

Вполне возможно, что события «before_insert» и before_update 'отлично для этого purpouse.

+0

Я, возможно, не очень хорошо объяснил. Я уже * вставляю * и * обновляю * ok путем таргетинга на «Organisation», а затем «OrganisationMap». Я хочу, чтобы иметь возможность * выбирать * связанные объекты на основе полей 'is_customer' или' is_supplier'. Например, 'organisation_1.associated' вернет список связанных организаций. Мне нужно сделать эквивалент для 'organisation_1.suppliers' или' organisation_1.customers' – user162390