SQLAlchemy 关系冲突

SQLAlchemy relationships conflict

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

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

我怎样才能把dog_id(狗)cat_id(猫)pet_id(盒子)?

我尝试了以下方法:

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'

如何正确建立关系?谢谢

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

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

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

你的结构看起来 polymorphic 你有一只宠物 class 和子 class 狗和猫。在mapper_args中定义多态类型。在 Boxes class 中添加外键。与宠物而不是狗或猫建立关系。宠物会根据pet_type.

帮你拥有狗或猫属性
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"}