【问题标题】:SQLAlchemy relationships conflictSQLAlchemy 关系冲突
【发布时间】:2022-01-01 11:55:05
【问题描述】:

我在表格中建立关系时遇到问题。

我需要把宠物放在盒子里。一盒 - 一只宠物。 宠物根据特性分为两个表。

我怎样才能把 dog_id(Dogs) cat_id(Cats) 放到 pet_id(Boxes) ?

我尝试了以下方法:

class Boxes():
    __tablename__ = 'Boxes table'

    box_id = Column('Box ID', NVARCHAR(5), primary_key=True)
    pet_id = Column('Pet ID', ForeignKey('Dogs table.DOG ID'), ForeignKey('Cats table.CAT ID'))
    
    pet_cat = relationship('Cats')
    pet_dog = relationship('Dogs')
    
class Dogs():
    __tablename__ = 'Dogs table'
    
    dog_id = Column('DOG ID', NVARCHAR(10), primary_key=True)
    dog_characteristics = Column('Dog Characteristics', NVARCHAR(20))

class Cats():
    __tablename__ = 'Cats table'
    
    cat_id = Column('CAT ID', NVARCHAR(10), primary_key=True)
    cat_characteristics = Column('Cat Characteristics', NVARCHAR(50))

但是有冲突:

relationship 'Boxes.pet_cat' will copy column Cats table.CAT ID to column Boxes table.Pet ID, which conflicts with relationship(s): 'Boxes.pet_dog'

我应该如何正确建立关系?谢谢

【问题讨论】:

    标签: python sql sqlalchemy


    【解决方案1】:

    你的结构看起来polymorphic 有一个宠物类和子类狗和猫。在 mapper_args 中定义多态类型。在 Boxes 类中添加外键。与宠物而不是狗或猫建立关系。 Pet 会根据 pet_type 帮助你拥有 Dog 或 Cat 属性。

    from sqlalchemy.orm import backref, relationship
    from sqlalchemy.sql.schema import Column, ForeignKey
    from sqlalchemy.sql.sqltypes import Integer, String
    
    class Boxes():
        __tablename__ = 'Boxes table'
    
        box_id = Column('Box ID', NVARCHAR(5), primary_key=True)
        pet_id = Column(Integer, ForeignKey('pet.id'))
        pet = relationship("Pet", backref=backref("boxes", cascade="all, delete-orphan", lazy=True))
    
    class Pet():
        __tablename__ = 'pet'
        id = Column(Integer, primary_key=True, autoincrement=True)
        name = Column(String)
        pet_type = Column(String)
    
        __mapper_args__ = {"polymorphic_identity": "pet", "polymorphic_on": pet_type}
    
    class Dogs(Pet):
        __tablename__ = 'Dogs table'
        
        id = Column(Integer, ForeignKey("pet.id"), primary_key=True)
        dog_characteristics = Column('Dog Characteristics', NVARCHAR(20))
        __mapper_args__ = {"polymorphic_identity": "pet_dog"}
    
    class Cats(Pet):
        __tablename__ = 'Cats table'
        
        id = Column(Integer, ForeignKey("pet.id"), primary_key=True)
        cat_characteristics = Column('Cat Characteristics', NVARCHAR(50))
        __mapper_args__ = {"polymorphic_identity": "pet_cat"}   
     
    

    【讨论】:

    • 好的,谢谢!我有这样的假设,但不知道如何正确地做出它。这在我无法将表连接在一起的情况下效果很好。
    【解决方案2】:

    您不能同时为两个表分配一个键。

    对于这种情况,为动物设计一个表,并给表一个类型字段,并将这个表的主键作为盒子表的外键。

    class Animals():
        __tablename__ = 'Animals table'
        
        animal_id = Column('Animal ID', NVARCHAR(10), primary_key=True)
        animal_characteristics = Column('Animal Characteristics', NVARCHAR(20))
        animal_type = Column('Animal Type', NVARCHAR(20))
    

    和盒子

    class Boxes():
        __tablename__ = 'Boxes table'
    
        box_id = Column('Box ID', NVARCHAR(5), primary_key=True)
        pet_id = Column('Pet ID', ForeignKey('Animals table.Animal ID'))
        
        pet_animal = relationship('Animals')
    

    【讨论】:

    • 如果可以将表格合并为一个,则效果很好。感谢您的帮助!
    猜你喜欢
    • 2021-08-05
    • 2018-01-15
    • 1970-01-01
    • 2020-10-07
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    相关资源
    最近更新 更多