2012-02-21 4 views
1

У меня есть класс местоположения. В местоположениях могут быть дефолтные «счета на адреса», которые также являются местоположениями. Поля, с которыми я работаю, - это bill_to_id и bill_to в классе CustomerLocation. Я включил родительский класс для полноты. Как я могу установить одно местоположение в качестве счета другого места? Отношения должны быть взаимно однозначными (у места будет только один счет). Никакой backref не требуется.SQLAlchemy, отношения один к одному в одной таблице

ТИА

class Location(DeclarativeBase,TimeUserMixin): 
    __tablename__ = 'locations' 

    location_id = Column(Integer,primary_key=True,autoincrement=True) 
    location_code = Column(Unicode(10)) 
    name = Column(Unicode(100)) 
    address_one = Column(Unicode(100)) 
    address_two = Column(Unicode(100)) 
    address_three = Column(Unicode(100)) 
    city = Column(Unicode(100)) 
    state_id = Column(Integer,ForeignKey('states.state_id')) 
    state_relate = relation('State') 
    zip_code = Column(Unicode(100)) 
    phone = Column(Unicode(100)) 
    fax = Column(Unicode(100)) 
    country_id = Column(Integer,ForeignKey('countries.country_id')) 
    country_relate = relation('Country') 
    contact = Column(Unicode(100)) 
    location_type = Column('type',Unicode(50)) 

    __mapper_args__ = {'polymorphic_on':location_type} 

class CustomerLocation(Location): 
    __mapper_args__ = {'polymorphic_identity':'customer'} 
    customer_id = Column(Integer,ForeignKey('customers.customer_id', 
              use_alter=True,name='fk_customer_id')) 
    customer = relation('Customer', 
         backref=backref('locations'), 
         primaryjoin='Customer.customer_id == CustomerLocation.customer_id') 
    tbred_ship_code = Column(Unicode(6)) 
    tbred_bill_to = Column(Unicode(6)) 
    ship_method_id = Column(Integer,ForeignKey('ship_methods.ship_method_id')) 
    ship_method = relation('ShipMethod',primaryjoin='ShipMethod.ship_method_id == CustomerLocation.ship_method_id') 
    residential = Column(Boolean,default=False,nullable=False) 
    free_shipping = Column(Boolean,default=False,nullable=False) 
    collect = Column(Boolean,default=False,nullable=False) 
    third_party = Column(Boolean,default=False,nullable=False) 
    shipping_account = Column(Unicode(50)) 
    bill_to_id = Column(Integer,ForeignKey('locations.location_id')) 
    bill_to = relation('CustomerLocation',remote_side=['locations.location_id']) 

ответ

2

Смотрите мой answer to a related question. Вы можете иметь самореферентные отношения в декларативном объявлении в качестве ссылочного внешнего ключа в таблице, а также «обезглавливать» класс сразу после объявления или указывать имена иностранных столбцов как строки, а не поля классов. Пример:

class Employee(Base): 
    __tablename__ = 'employee' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(64), nullable=False) 
Employee.manager_id = Column(Integer, ForeignKey(Employee.id)) 
Employee.manager = relationship(Employee, backref='subordinates', 
    remote_side=Employee.id) 

Я успешно использовал эту технику, перед которой дает вам оба направления отношений родитель-ребенок дерево (где один из родителей может иметь несколько дочерних записей). Если вы опустите аргумент backref, он может работать или не работать для вас. Вы всегда можете просто использовать только одно направление отношений в своем приложении.

+0

Мне не удалось заставить его работать через строки, но, используя ваш явный пример, сообщение Employee Declaration, действительно сработало. Спасибо! – jheld

Смежные вопросы