Как автозаполнить таблицу внешними ключами в SQLAlchemy с использованием отношений?

#python #sql #sqlalchemy #orm #flask-sqlalchemy

#python #sql #sql — алхимия #orm #flask-sqlalchemy

Вопрос:

Используя SQLAlchemy, у меня есть три модели: Parent1, Parent2 и Child, где Parent1 имеет взаимно однозначные отношения с Parent2, и оба они имеют одинаковые отношения с Child . Вот они:

 from extensions import db_session

class Parent1(Base):
    __tablename__ = 'parent1'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    
    parent2 = relationship("Parent2", backref="parent1", uselist=False)
    child = relationship("Child", backref="parent1", uselist=False)



class Parent2(Base):
    __tablename__ = 'parent2'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    parent1_id = Column(Integer, ForeignKey('parent1.id'))

    child = relationship("Child", backref="parent2", uselist=False)

class Child(Base):
    id = Column(Integer, primary_key=True)
    parent1_id = Column(Integer, ForeignKey('parent1.id'))
    parent2_id = Column(Integer, ForeignKey('parent2.id'))
 

Чего я пытаюсь добиться, так это заполнить дочернюю таблицу внешними ключами ее родителей.
Итак, когда я выполняю это:

 parent1 = Parent1(name="Adil")
parent1.parent2 = Parent2(name="Aisha")
parent1.child = Child()
db_session.add(parent1)
db_session.commit()
 

в родительские таблицы он вставляет данные по мере необходимости, однако в дочернюю таблицу он вставляет данные следующим образом:

Ребенок

 id  parent1_id  parent2_id
 1           1        NULL
 

Как правильно установить отношения, чтобы при любой вставке в таблицы Parent1-> Parent2 он также вставлял свои идентификаторы в качестве внешних ключей в дочернюю таблицу?

Чего я хочу добиться, так это:

Ребенок

 id  parent1_id  parent2_id
 1           1           1
 

Ответ №1:

Я придумал это решение. Я удалил объявленный дочерний элемент модели и создал ассоциативную таблицу между двумя моделями, а также добавил заполнение вторичных параметров именем ассоциативной таблицы:

 Base = declarative_base()

child = Table('child', Base.metadata,
               Column('parent1_id', Integer, ForeignKey('parent1.id')),
               Column('parent2_id', Integer, ForeignKey('parent2.id')))


class Parent1(Base):
    __tablename__ = 'parent1'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)

    parent2 = relationship("Parent2", secondary='child', uselist=False)


class Parent2(Base):
    __tablename__ = 'parent2'
    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False)
    parent1_id = Column(Integer, ForeignKey('parent1.id'))