【问题标题】:SQLAlchemy, one to one relationship on the same tableSQLAlchemy,同一张表上的一对一关系
【发布时间】:2012-02-21 16:47:52
【问题描述】:

我有一个位置类。位置可以有默认的“地址帐单”,它们也是位置。我正在使用的字段是 CustomerLocation 类中的 bill_to_idbill_to。为了完整起见,我已经将父类包括在内。如何将一个位置设置为另一个位置的收单方?这种关系应该是一对一的(一个位置永远只有一个账单)。不需要反向引用。

TIA

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'])

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    见我的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 参数,它可能对您有用,也可能对您无效。您总是可以简单地选择在您的应用程序中仅使用一个方向的关系。

    【讨论】:

    • 我无法让它通过字符串工作,但使用您的明确示例发布员工声明,确实有效。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 2011-10-04
    • 1970-01-01
    相关资源
    最近更新 更多