es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Conflictos en las relaciones de SQLAlchemy

Tengo un problema con la formación de relaciones en una tabla.

Necesito poner a las mascotas en cajas. Una caja – una mascota.
Las mascotas se dividen en dos tablas según sus características.

¿Cómo puedo poner el “dog_id” (Perros) o “cat_id” (Gatos) en el “pet_id” (Cajas)?

He intentado lo siguiente:

class Cajas():
    tablename = 'Tabla de cajas'

    box_id = Column('Box ID', NVARCHAR(5), primary_key=True)
    pet_id = Column('Pet ID', ForeignKey('Tabla de perros.DOG ID'), ForeignKey('Tabla de gatos.CAT ID'))

    pet_cat = relationship('Gatos')
    pet_dog = relationship('Perros')


class Perros():
    tablename = 'Tabla de perros'

    dog_id = Column('DOG ID', NVARCHAR(10), primary_key=True)
    dog_characteristics = Column('Características del perro', NVARCHAR(20))


class Gatos():
    tablename = 'Tabla de gatos'

    cat_id = Column('CAT ID', NVARCHAR(10), primary_key=True)
    cat_characteristics = Column('Características del gato', NVARCHAR(50))

Pero hay un conflicto:

La relación ‘Boxes.pet_cat’ copiará la columna ‘Cats table.CAT ID’ en la columna ‘Boxes table.Pet ID’, lo que entra en conflicto con la(s) relación(es): ‘Boxes.pet_dog’.
¿Cómo debo establecer correctamente una relación? Gracias.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Puede intentar usar una relación polimórfica, lo que le permite vincular la columna pet_id en la tabla Boxes con las columnas dog_id y cat_id en sus respectivas tablas.

    Aquí hay una implementación de ejemplo:

    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey, polymorphic_union
    from sqlalchemy.orm import relationship
    
    Base = declarative_base()
    
    class Pet(Base):
        __tablename__ = 'pets'
        pet_id = Column(Integer, primary_key=True)
        pet_type = Column(String)
    
        __mapper_args__ = {
            'polymorphic_identity': 'pet',
            'polymorphic_on': pet_type
        }
    
    class Dog(Pet):
        __tablename__ = 'dogs'
        dog_id = Column(Integer, ForeignKey('pets.pet_id'), primary_key=True)
        dog_characteristics = Column(String)
    
        __mapper_args__ = {'polymorphic_identity': 'dog'}
    
    class Cat(Pet):
        __tablename__ = 'cats'
        cat_id = Column(Integer, ForeignKey('pets.pet_id'), primary_key=True)
        cat_characteristics = Column(String)
    
        __mapper_args__ = {'polymorphic_identity': 'cat'}
    
    class Box(Base):
        __tablename__ = 'boxes'
        box_id = Column(Integer, primary_key=True)
        pet_id = Column(Integer, ForeignKey('pets.pet_id'))
        pet = relationship(Pet, polymorphic_on=pet_id, backref='boxes')
    

    En esta implementación, tenemos una tabla Pet con una columna pet_type que nos permite distinguir entre perros y gatos. Luego tenemos tablas separadas para Dog y Cat, que heredan de Pet.

    La tabla Box tiene una columna pet_id que está vinculada a la columna pet_id en la tabla Pet utilizando una relación polimórfica. Esto permite que un objeto Box haga referencia tanto a objetos Dog como Cat utilizando la misma columna.

    Usando este enfoque, debería poder agregar un objeto Box para cada mascota y vincularlo con el objeto Dog o Cat correspondiente.

Comments are closed.