谁能告诉我的人际关系出了啥问题?

Posted

技术标签:

【中文标题】谁能告诉我的人际关系出了啥问题?【英文标题】:Can anyone tell whats wrong with my relationships?谁能告诉我的人际关系出了什么问题? 【发布时间】:2012-12-23 10:49:44 【问题描述】:

我正在使用 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 关系配置文档中记录的One to Many 关系。

【讨论】:

【参考方案2】:

您应该在 Post 模型中添加一个字段,内容如下:

thread_id = Column(Integer, ForeignKey("thread.id"), nullable=True, default=None)

SQLAlchemy 应该如何知道您定义的这种关系应该如何将线程链接到帖子?这就是为什么你应该有一个从帖子到它的线程的外键。您可以允许它为空,如果它不属于线程,则取决于您的用例。

【讨论】:

很好的答案,但我要把它交给 martijn @JakobBowyer 不用担心!

以上是关于谁能告诉我的人际关系出了啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

在我的第一个视图 Django 中如何/出了啥问题

一些测试用例失败了。告诉我出了啥问题

检测到致命错误 - 如何知道出了啥问题

SPOJ 问题 - 这里出了啥问题?

当 Visual Studio 告诉我“xcopy 以代码 4 退出”时出了啥问题

我的 SQL 查询出了啥问题?