Может ли кто-нибудь сказать, что случилось с моими отношениями?
Я использую sqlalchemy для создания сайта стиля форума. Я начал выбивать дизайн, но каждый раз, когда я пытаюсь проверить его с помощью нескольких вставок, он сбрасывает кирпич,
NoForeignKeysError: Could not determine join condition between parent/child
tables on relationship Thread.replies - there are no foreign keys linking
these tables. Ensure that referencing columns are associated with a
ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
Вот мои "модели"
from sqlalchemy import Integer, Column, String, create_engine, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker, backref
from .database import Base # declarative base instance
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
username = Column(String, unique=True)
email = Column(String, unique=True)
threads = relationship("Thread", backref="user")
posts = relationship("Post", backref="user")
class Post(Base):
__tablename__ = "post"
id = Column(Integer, primary_key=True)
name = Column(String)
body = Column(String)
author = Column(Integer, ForeignKey("user.id"))
class Thread(Base):
__tablename__ = "thread"
id = Column(Integer, primary_key=True)
name = Column(String)
desc = Column(String)
replies = relationship("Post", backref="thread")
author_id = Column(Integer, ForeignKey("user.id"))
board_id = Column(Integer, ForeignKey("board.id"))
class Board(Base):
__tablename__ = "board"
id = Column(Integer, primary_key=True)
name = Column(String)
desc = Column(String)
threads = relationship("Thread", backref="board")
category_id = Column(Integer, ForeignKey("category.id"))
class Category(Base):
__tablename__ = "category"
id = Column(Integer, primary_key=True)
name = Column(String)
desc = Column(String)
threads = relationship("Board", backref="category")
engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(engine)
session_factory = sessionmaker(bind=engine)
session = session_factory()
Ответы
Ответ 1
В вашей модели Post
нет ссылки thread
. Добавьте столбец в Post
, ссылаясь на thread
, сообщение принадлежит:
class Post(Base):
__tablename__ = "post"
id = Column(Integer, primary_key=True)
name = Column(String)
body = Column(String)
author = Column(Integer, ForeignKey("user.id"))
thread_id = Column(Integer, ForeignKey('thread.id'))
Мы не можем использовать имя thread
, потому что то, что отношение Post.replies
добавит к извлеченным экземплярам thread
.
Это отношение от одного до большого, как описано в документации по настройке отношений SQLAlchemy.
Ответ 2
Вы должны добавить поле в модели Post, которое гласит:
thread_id = Column(Integer, ForeignKey("thread.id"), nullable=True, default=None)
Как SQLAlchemy должен знать, как это отношение, которое вы определили, должно связывать thhread с сообщением? Вот почему у вас должен быть внешний ключ из сообщения в его поток. Вы можете разрешить ему быть нулевым, если он не принадлежит нити, это зависит от вашего прецедента.