Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anyone tell whats wrong with my relationships?

Im using sqlalchemy to design a forum style website. I started knocking out the design but everytime I try to test it with a few inserts, it dumps a brick;

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.

Here are my "models"

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()
like image 837
Jakob Bowyer Avatar asked Dec 23 '12 10:12

Jakob Bowyer


People also ask

What is stonewalling in a relationship?

What does it mean to stonewall someone? In simple terms, stonewalling is when someone completely shuts down in a conversation or refuses to interact with another person.


1 Answers

Your Post model has no thread reference. Add a column to Post referencing the Thread a post belongs to:

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'))

We can't use the name thread because that's what the Post.replies relationship will add to retrieved Thread instances.

This is a One to Many relationship as documented in the SQLAlchemy Relationship Configuration documentation.

like image 188
Martijn Pieters Avatar answered Nov 05 '22 16:11

Martijn Pieters