Search code examples
pythondatabasesqlalchemyrelationshiprelational

SQLAlchemy Using relationship()


I am using SQLAlchemy here, trying to make a couple tables and link them and am having problems implementing this.

class Team(Base):

    __tablename__ = "teams"

    id = Column(Integer, primary_key=True)
    espn_team_id = Column(Integer, unique=True, nullable=False)
    games = relationship("Game", order_by="Game.date")

    def __init__(self, name):
        self.name = name
        self.espn_team_id = espn_team_id
        self.games = games

class Game(Base):
    __tablename__ = "games"

    id = Column(Integer, primary_key=True)
    espn_game_id=Column(Integer, unique=True, nullable=False)
    date = Column(Date)

    h_espn_id = Column(Integer, ForeignKey('teams.espn_team_id'))
    a_espn_id = Column(Integer, ForeignKey('teams.espn_team_id'))

I have this in one file which I use to create the tables. Then in another file I use the insert() function to put values into both tables. I think if I have a team with espn_team_id 360, and then I put in multiple games into the game table which have either h_espn_id=360, or a_espn_id=360, i should be able to do:

a = Table("teams", metadata, autoload=True)
a = session.query(a).filter(a.c.espn_team_id==360).first().games 

and it should give me a list of all games team with ID 360 has played. But instead I get this error

AttributeError: 'NamedTuple' object has no attribute 'games'

What am I misunderstanding about SQLAlchemy or relational databases here?


Solution

  • Here is the solution I found, took way too long to understand this...

    class Team(Base):
    
        __tablename__ = "teams"
    
        id = Column(Integer, primary_key=True)
        name = Column(String)
        espn_team_id = Column(Integer, unique=True, nullable=False)
    
        h_games = relationship(
                      "Game", 
                      primaryjoin="Game.h_espn_id==Team.espn_team_id", 
                      order_by="Game.date")
        a_games = relationship(
                      "Game", 
                      primaryjoin="Game.a_espn_id==Team.espn_team_id", 
                      order_by="Game.date")
    
        @hybrid_property
        def games(self):
            return self.h_games+self.a_games
    
        def __init__(self, name):
            self.name = name
            self.espn_team_id = espn_team_id
            self.h_games = h_games
            self.a_games = a_games
            self.games = games