@k0r0g

Как указать Foreign key не создавая его в базе данных?

Была таблица, определённая как
class Child(db.Model):
    __tablename__ = 'childs'
    id = Column(Integer, autoincrement=True)
    parent_id = Column(Integer, ForeignKey("parents.id", ondelete="CASCADE"), nullable=False)
    parent = relationship("Parent")

Специфика такая, что в таблице Child много миллионов записей. Было решено отказаться от FK constraint'ов, чтобы ускорить удаления и изменения на Parent таблице.
Нагуглил решение, которое не создаёт FK при генерации миграций alembic'ом:
class Child(db.Model):
    __tablename__ = 'childs'
    id = Column(Integer, autoincrement=True)
    parent_id = Column(Integer, nullable=False)
    parent = relationship("Parent", primaryjoin='foreign(Child.parent_id) == Parent.id')

С ним вылезли следующие проблемы:
1. SQLAlchemyAutoSchema не исключает поле parent_id из схемы, так как foreign key для него не указан. (include_fk=False)
class ChildsSchema(SQLAlchemyAutoSchema):
    parent = Related(required=True)
    class Meta:
        model = Child

Можно решить через exclude, но не хочется делать это везде.
2. Более серьёзная проблема в join'ах, которые мы раньше указывали так:
query = select(Child.id,...).join(Parent)
Теперь sqlalchemy требует указывать ON condition: .join(Parent, Child.parent_id == Parent.id). Тоже придётся делать это везде. Хотя я надеялся, что аннотация в relationship хотя бы с этим поможет.

Итого, для реализации задуманного выбираю между двумя вариантами:
1. Добавить везде явные условия join'a и exclude'ы. Тут нужно сказать, что таких связок Parent-Child, где нужно удалить constraint довольно много.
2. В алембике переопределить include_object, который не будет создавать эти costraint'ы. Выглядит для меня не очень явным.

Есть ли какой-то способ получить 2 в 1?
  • Вопрос задан
  • 53 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы