【问题标题】:Many-to-one relationship of two models inheriting from the same polymorphic type in sqlalchemy从sqlalchemy中的相同多态类型继承的两个模型的多对一关系
【发布时间】:2020-03-15 14:28:05
【问题描述】:

我有一个多态基类,例如:

class Addressable(Base):
    addressable_id = Column(Integer, nullable=False, primary_key=True)
    addressable_type = Column(String, nullable=False)
    addresses = relationship('Address')

    __mapper_args__ = {'polymoprhic_on': addressable_type}

这用于允许子类添加任意数量的地址:

class Address(Base):
    # ...
    addressable_id = Column(Integer, ForeignKey('Addressable.addressable_id')

据我的(到目前为止,有限的)测试可以看出,这部分有效。没有的是两个子类彼此之间具有多对一的关系。

class CompanyLocation(Addressable):
   __mapper_args_ = {'polymprophic_identity': 'CompanyLocation'}
   company_location_id = Column(Integer, ForeignKey(Addressable.addressable_id), primary_key=True)
   company_id = Column(CompanyId, ForeignKey('Company.company_id'), nullable=False)

class Company(Addressable):
    __mapper_args_ = {'polymorphic_identity': 'Company'}
    company_id = Column(Integer, ForeignKey(Addressable.addressable_id), primary_key=True)
    locations = relationship(CompanyLocation, foreign_keys=CompanyLocation.company_location_id,
                             backref='company')

测试时,如果我这样做:

company = Company() 
company.addresses.append(Address(name='foo'))
location = CompanyLocation()
company.locations.append(location)
session.add(company)
session.commit()

assert company.addresses[0].name == 'foo'  # Works!
assert company.locations[0] == location

我明白了,令人费解的是:

E    assert <Company object at 0x119e151d0> == <CompanyLocation object at 0x117edc950>

不知何故,locations 拥有公司本身的价值,而不是其位置。如果我尝试向公司添加第二个位置,则操作将失败,因为该条目不是唯一的(这是有道理的,因为它以某种方式使用自己的 PK 作为 FK?)同样,location.company 会返回 CustomerLocation对象。

如果我删除append 调用,并将customer = relationship('Customer', foreign_keys=customer_id, back_populates='locations') 显式添加到CompanyLocation 类,则对company.locations 的调用结果为一个空列表。然而,这样做确实至少修复了对location.company的调用


我做了什么?

我们正在使用 PostgresQL,并且正在使用 sqlalchemy 1.3.11

就上下文而言,这里的用例是我们的客户需要将地址附加到公司实体(例如,帐单地址),该地址可能不同于他们各自位置的地址(其中一些也有自己的帐单,而不是其他地址)。邮寄地址)。

【问题讨论】:

    标签: python-3.x database sqlalchemy


    【解决方案1】:

    好吧,在尝试了几种不同的解决方案后,我让它工作了。我仍然不明白为什么上述失败了,但是在我使用 primaryjoin 而不是 foreign_keys 之后一切正常,例如,

    class Company:
        # . . .
        locations = relationship("CompanyLocation", back_populates='company', primaryjoin='Company.company_id == CompanyLocation.company_id')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-07
      • 2017-06-10
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 2013-10-20
      相关资源
      最近更新 更多