'Table' object has no attribute 'id' on SQLAlchemy relation2019 Community Moderator ElectionHow to sort a list of objects based on an attribute of the objects?How to know if an object has an attribute in PythonDetermine the type of an object?Formalchemy - form for one to many relationHow to force aliases for columns in SQLAlchemy?Getting warning when 2 models inherit the same object in flask-sqlalchemyPython: sqlalchemy the result of schema isn't expectedHow to initialize the object (table) using dict with some relationship with other table via sqlalchemy?SQLAlchemy “AttributeError: 'str' object has no attribute 'c'”How to count child table items with or without join to parent table using SQLAlchemy?

Why Choose Less Effective Armour Types?

What is a ^ b and (a & b) << 1?

As a new Ubuntu desktop 18.04 LTS user, do I need to use ufw for a firewall or is iptables sufficient?

What exactly is this small puffer fish doing and how did it manage to accomplish such a feat?

"Words were different when they (lived / were living) inside of you"

Official degrees of earth’s rotation per day

Print a physical multiplication table

Is it insecure to send a password in a `curl` command?

Simplify an interface for flexibly applying rules to periods of time

Knife as defense against stray dogs

If I can solve Sudoku, can I solve the Travelling Salesman Problem (TSP)? If so, how?

How difficult is it to simply disable/disengage the MCAS on Boeing 737 Max 8 & 9 Aircraft?

Explaining pyrokinesis powers

What is the adequate fee for a reveal operation?

Is there a hypothetical scenario that would make Earth uninhabitable for humans, but not for (the majority of) other animals?

Happy pi day, everyone!

Relationship between sampajanna definitions in SN 47.2 and SN 47.35

If I am holding an item before I cast Blink, will it move with me through the Ethereal Plane?

Examples of transfinite towers

How to pronounce "I ♥ Huckabees"?

Describing a chess game in a novel

A single argument pattern definition applies to multiple-argument patterns?

ERC721: How to get the owned tokens of an address

Why is the President allowed to veto a cancellation of emergency powers?



'Table' object has no attribute 'id' on SQLAlchemy relation



2019 Community Moderator ElectionHow to sort a list of objects based on an attribute of the objects?How to know if an object has an attribute in PythonDetermine the type of an object?Formalchemy - form for one to many relationHow to force aliases for columns in SQLAlchemy?Getting warning when 2 models inherit the same object in flask-sqlalchemyPython: sqlalchemy the result of schema isn't expectedHow to initialize the object (table) using dict with some relationship with other table via sqlalchemy?SQLAlchemy “AttributeError: 'str' object has no attribute 'c'”How to count child table items with or without join to parent table using SQLAlchemy?










1















I've got a relationship set up across three separate classes using SQLAlchemy, with an association table for a many-to-many relationship. Minimal example:



from sqlalchemy import * 
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import configure_mappers, relationship

Base = declarative_base()

teams_users = Table(
'teams_users', Base.metadata,
Column('team_id', ForeignKey('teams.id')),
Column('user_id', ForeignKey('users.id'))
)

class User(Base):
__tablename__ = 'users'
# No autoincrement, since we're using externally-generated UIDs
id = Column(Integer, primary_key=True, autoincrement=False)
teams = relationship('Team', secondary=teams_users, back_populates="users")

class Team(Base):
__tablename__ = 'teams'
id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
game_id = Column(Integer, ForeignKey('games.id'), nullable=False)
games = relationship("Game", foreign_keys='games.id')
users = relationship("User", secondary='teams_users', back_populates="teams")

class Game(Base):
__tablename__ = 'games'
id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
team1_id = Column(Integer, ForeignKey('teams.id'))
team2_id = Column(Integer, ForeignKey('teams.id'))
team1 = relationship("Team", back_populates="games", foreign_keys=team1_id, uselist=False)
tean2 = relationship("Team", back_populates="games", foreign_keys=team2_id, uselist=False)

# done declaring, trigger the error
configure_mappers()


Attempting to query any of these relations returns a 'Table' object has no attribute 'id' error:



Traceback (most recent call last):
File "...", line 35, in <module>
configure_mappers()
File "/.../sqlalchemy/orm/mapper.py", line 3033, in configure_mappers
mapper._post_configure_properties()
File "/.../sqlalchemy/orm/mapper.py", line 1832, in _post_configure_properties
prop.init()
File "/.../sqlalchemy/orm/interfaces.py", line 183, in init
self.do_init()
File "/.../sqlalchemy/orm/relationships.py", line 1655, in do_init
self._process_dependent_arguments()
File "/.../sqlalchemy/orm/relationships.py", line 1680, in _process_dependent_arguments
setattr(self, attr, attr_value())
File "/.../sqlalchemy/ext/declarative/clsregistry.py", line 281, in __call__
x = eval(self.arg, globals(), self._dict)
File "<string>", line 1, in <module>
AttributeError: 'Table' object has no attribute 'id'


My goal in constructing it this way is that I could easily check which Teams each User has ever been a part of.



Additionally, Game has two foreign keys into Team because the use case for this project supports arbitrarily sized teams, but only ever two teams. This allows me to have a result of "team1 won" and immediately have a reference to the winning users for stat tracking and historical reference.



What am I doing wrong here?










share|improve this question




























    1















    I've got a relationship set up across three separate classes using SQLAlchemy, with an association table for a many-to-many relationship. Minimal example:



    from sqlalchemy import * 
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import configure_mappers, relationship

    Base = declarative_base()

    teams_users = Table(
    'teams_users', Base.metadata,
    Column('team_id', ForeignKey('teams.id')),
    Column('user_id', ForeignKey('users.id'))
    )

    class User(Base):
    __tablename__ = 'users'
    # No autoincrement, since we're using externally-generated UIDs
    id = Column(Integer, primary_key=True, autoincrement=False)
    teams = relationship('Team', secondary=teams_users, back_populates="users")

    class Team(Base):
    __tablename__ = 'teams'
    id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
    game_id = Column(Integer, ForeignKey('games.id'), nullable=False)
    games = relationship("Game", foreign_keys='games.id')
    users = relationship("User", secondary='teams_users', back_populates="teams")

    class Game(Base):
    __tablename__ = 'games'
    id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
    team1_id = Column(Integer, ForeignKey('teams.id'))
    team2_id = Column(Integer, ForeignKey('teams.id'))
    team1 = relationship("Team", back_populates="games", foreign_keys=team1_id, uselist=False)
    tean2 = relationship("Team", back_populates="games", foreign_keys=team2_id, uselist=False)

    # done declaring, trigger the error
    configure_mappers()


    Attempting to query any of these relations returns a 'Table' object has no attribute 'id' error:



    Traceback (most recent call last):
    File "...", line 35, in <module>
    configure_mappers()
    File "/.../sqlalchemy/orm/mapper.py", line 3033, in configure_mappers
    mapper._post_configure_properties()
    File "/.../sqlalchemy/orm/mapper.py", line 1832, in _post_configure_properties
    prop.init()
    File "/.../sqlalchemy/orm/interfaces.py", line 183, in init
    self.do_init()
    File "/.../sqlalchemy/orm/relationships.py", line 1655, in do_init
    self._process_dependent_arguments()
    File "/.../sqlalchemy/orm/relationships.py", line 1680, in _process_dependent_arguments
    setattr(self, attr, attr_value())
    File "/.../sqlalchemy/ext/declarative/clsregistry.py", line 281, in __call__
    x = eval(self.arg, globals(), self._dict)
    File "<string>", line 1, in <module>
    AttributeError: 'Table' object has no attribute 'id'


    My goal in constructing it this way is that I could easily check which Teams each User has ever been a part of.



    Additionally, Game has two foreign keys into Team because the use case for this project supports arbitrarily sized teams, but only ever two teams. This allows me to have a result of "team1 won" and immediately have a reference to the winning users for stat tracking and historical reference.



    What am I doing wrong here?










    share|improve this question


























      1












      1








      1








      I've got a relationship set up across three separate classes using SQLAlchemy, with an association table for a many-to-many relationship. Minimal example:



      from sqlalchemy import * 
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy.orm import configure_mappers, relationship

      Base = declarative_base()

      teams_users = Table(
      'teams_users', Base.metadata,
      Column('team_id', ForeignKey('teams.id')),
      Column('user_id', ForeignKey('users.id'))
      )

      class User(Base):
      __tablename__ = 'users'
      # No autoincrement, since we're using externally-generated UIDs
      id = Column(Integer, primary_key=True, autoincrement=False)
      teams = relationship('Team', secondary=teams_users, back_populates="users")

      class Team(Base):
      __tablename__ = 'teams'
      id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
      game_id = Column(Integer, ForeignKey('games.id'), nullable=False)
      games = relationship("Game", foreign_keys='games.id')
      users = relationship("User", secondary='teams_users', back_populates="teams")

      class Game(Base):
      __tablename__ = 'games'
      id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
      team1_id = Column(Integer, ForeignKey('teams.id'))
      team2_id = Column(Integer, ForeignKey('teams.id'))
      team1 = relationship("Team", back_populates="games", foreign_keys=team1_id, uselist=False)
      tean2 = relationship("Team", back_populates="games", foreign_keys=team2_id, uselist=False)

      # done declaring, trigger the error
      configure_mappers()


      Attempting to query any of these relations returns a 'Table' object has no attribute 'id' error:



      Traceback (most recent call last):
      File "...", line 35, in <module>
      configure_mappers()
      File "/.../sqlalchemy/orm/mapper.py", line 3033, in configure_mappers
      mapper._post_configure_properties()
      File "/.../sqlalchemy/orm/mapper.py", line 1832, in _post_configure_properties
      prop.init()
      File "/.../sqlalchemy/orm/interfaces.py", line 183, in init
      self.do_init()
      File "/.../sqlalchemy/orm/relationships.py", line 1655, in do_init
      self._process_dependent_arguments()
      File "/.../sqlalchemy/orm/relationships.py", line 1680, in _process_dependent_arguments
      setattr(self, attr, attr_value())
      File "/.../sqlalchemy/ext/declarative/clsregistry.py", line 281, in __call__
      x = eval(self.arg, globals(), self._dict)
      File "<string>", line 1, in <module>
      AttributeError: 'Table' object has no attribute 'id'


      My goal in constructing it this way is that I could easily check which Teams each User has ever been a part of.



      Additionally, Game has two foreign keys into Team because the use case for this project supports arbitrarily sized teams, but only ever two teams. This allows me to have a result of "team1 won" and immediately have a reference to the winning users for stat tracking and historical reference.



      What am I doing wrong here?










      share|improve this question
















      I've got a relationship set up across three separate classes using SQLAlchemy, with an association table for a many-to-many relationship. Minimal example:



      from sqlalchemy import * 
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy.orm import configure_mappers, relationship

      Base = declarative_base()

      teams_users = Table(
      'teams_users', Base.metadata,
      Column('team_id', ForeignKey('teams.id')),
      Column('user_id', ForeignKey('users.id'))
      )

      class User(Base):
      __tablename__ = 'users'
      # No autoincrement, since we're using externally-generated UIDs
      id = Column(Integer, primary_key=True, autoincrement=False)
      teams = relationship('Team', secondary=teams_users, back_populates="users")

      class Team(Base):
      __tablename__ = 'teams'
      id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
      game_id = Column(Integer, ForeignKey('games.id'), nullable=False)
      games = relationship("Game", foreign_keys='games.id')
      users = relationship("User", secondary='teams_users', back_populates="teams")

      class Game(Base):
      __tablename__ = 'games'
      id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
      team1_id = Column(Integer, ForeignKey('teams.id'))
      team2_id = Column(Integer, ForeignKey('teams.id'))
      team1 = relationship("Team", back_populates="games", foreign_keys=team1_id, uselist=False)
      tean2 = relationship("Team", back_populates="games", foreign_keys=team2_id, uselist=False)

      # done declaring, trigger the error
      configure_mappers()


      Attempting to query any of these relations returns a 'Table' object has no attribute 'id' error:



      Traceback (most recent call last):
      File "...", line 35, in <module>
      configure_mappers()
      File "/.../sqlalchemy/orm/mapper.py", line 3033, in configure_mappers
      mapper._post_configure_properties()
      File "/.../sqlalchemy/orm/mapper.py", line 1832, in _post_configure_properties
      prop.init()
      File "/.../sqlalchemy/orm/interfaces.py", line 183, in init
      self.do_init()
      File "/.../sqlalchemy/orm/relationships.py", line 1655, in do_init
      self._process_dependent_arguments()
      File "/.../sqlalchemy/orm/relationships.py", line 1680, in _process_dependent_arguments
      setattr(self, attr, attr_value())
      File "/.../sqlalchemy/ext/declarative/clsregistry.py", line 281, in __call__
      x = eval(self.arg, globals(), self._dict)
      File "<string>", line 1, in <module>
      AttributeError: 'Table' object has no attribute 'id'


      My goal in constructing it this way is that I could easily check which Teams each User has ever been a part of.



      Additionally, Game has two foreign keys into Team because the use case for this project supports arbitrarily sized teams, but only ever two teams. This allows me to have a result of "team1 won" and immediately have a reference to the winning users for stat tracking and historical reference.



      What am I doing wrong here?







      python sqlalchemy






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 7 at 15:49









      Martijn Pieters♦

      720k14025172323




      720k14025172323










      asked Mar 7 at 15:34









      Mikey T.K.Mikey T.K.

      6111131




      6111131






















          1 Answer
          1






          active

          oldest

          votes


















          2














          To define the relationship between a game and the two teams that play in it, you need to only give the games table foreign keys; a team can play in multiple games, a one-to-many relationship; remove the games_id column altogether. The exception you got is a bit of a red herring, but it fails to properly configure the foreign_keys='games.id' argument in a relationship that doesn't need that foreign key.



          The relationship configuration on the Team class is a little tricky here as the Team.games attribute would have to relate to either foreign key. This is covered in the documentation under Handling Multiple Join Paths; you were almost there but there is no uselist parameter needed here:



          class Game(Base):
          __tablename__ = 'games'
          id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
          team1_id = Column(Integer, ForeignKey('teams.id'))
          team2_id = Column(Integer, ForeignKey('teams.id'))
          team1 = relationship("Team", foreign_keys=team1_id)
          team2 = relationship("Team", foreign_keys=team2_id)


          Note that I omitted the back_populates references here, because two relationships updating a single relationship on the other site leads one or the other of the two foreign keys being updated with the other value, leading to a game between the same team on either side!



          The inverse relationship attribute, Team.games, requires a custom primaryjoin because you are looking for games where either team1_id or team2_id is the foreign key pointing back. Use the foreign() annotation to help SQLAlchemy determine when to update the relationship (it'll watch for the foreign key changes), and use a lambda to defer resolving the columns:



          class Team(Base):
          __tablename__ = 'teams'
          id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
          # game_id = Column(Integer, ForeignKey('games.c.id'), nullable=False)
          games = relationship(
          "Game",
          primaryjoin=lambda: or_(
          Team.id == foreign(Game.team1_id),
          Team.id == foreign(Game.team2_id)
          ),
          viewonly=True,
          )
          users = relationship("User", secondary='teams_users', back_populates="teams")


          You could also make primaryjoin a string containing the expression now being executed in a lambda, so 'or_(Team.id == foreign(Game.team1_id), Team.id == foreign(Game.team2_id))'.



          Again, no back_populates, this type of relationship can't automatically update relationships between loaded objects. If you need to see these relationships reflected before committing, you'll need to issue a session flush. I also added viewonly=True, because you can't map mutations to the Team.games list to updates in the database (what would adding a new game to the list mean, that this team is team 1 or team 2?).



          You may want to add a custom constraint table to ensure that games never take place between the same team on both sides:



          class Game(Base):
          # ...
          __table_args__ = (
          CheckConstraint(team1_id != team2_id, name='different_teams'),
          )


          A quick demonstration of the relationships:



          from itertools import combinations

          engine = create_engine('sqlite:///:memory:', echo=False)
          Base.metadata.create_all(engine)
          session = sessionmaker(bind=engine)()

          teams = [Team() for _ in range(3)]
          session.add_all(teams)
          user = User(id=42, teams=teams)
          session.add(user)

          games = [Game(team1=t1, team2=t2) for t1, t2 in combinations(teams, 2)]
          session.add_all(games)
          session.commit()

          for team in user.teams:
          print('Team:', team.id, 'games:', [g.id for g in team.games])
          for game in session.query(Game):
          print(f'Game game.id: team game.team1.id vs game.team2.id')


          which outputs:



          Team: 2 games: [1, 3]
          Team: 1 games: [1, 2]
          Team: 3 games: [2, 3]
          Game 1: team 1 vs 2
          Game 2: team 1 vs 3
          Game 3: team 2 vs 3





          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55047510%2ftable-object-has-no-attribute-id-on-sqlalchemy-relation%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            To define the relationship between a game and the two teams that play in it, you need to only give the games table foreign keys; a team can play in multiple games, a one-to-many relationship; remove the games_id column altogether. The exception you got is a bit of a red herring, but it fails to properly configure the foreign_keys='games.id' argument in a relationship that doesn't need that foreign key.



            The relationship configuration on the Team class is a little tricky here as the Team.games attribute would have to relate to either foreign key. This is covered in the documentation under Handling Multiple Join Paths; you were almost there but there is no uselist parameter needed here:



            class Game(Base):
            __tablename__ = 'games'
            id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
            team1_id = Column(Integer, ForeignKey('teams.id'))
            team2_id = Column(Integer, ForeignKey('teams.id'))
            team1 = relationship("Team", foreign_keys=team1_id)
            team2 = relationship("Team", foreign_keys=team2_id)


            Note that I omitted the back_populates references here, because two relationships updating a single relationship on the other site leads one or the other of the two foreign keys being updated with the other value, leading to a game between the same team on either side!



            The inverse relationship attribute, Team.games, requires a custom primaryjoin because you are looking for games where either team1_id or team2_id is the foreign key pointing back. Use the foreign() annotation to help SQLAlchemy determine when to update the relationship (it'll watch for the foreign key changes), and use a lambda to defer resolving the columns:



            class Team(Base):
            __tablename__ = 'teams'
            id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
            # game_id = Column(Integer, ForeignKey('games.c.id'), nullable=False)
            games = relationship(
            "Game",
            primaryjoin=lambda: or_(
            Team.id == foreign(Game.team1_id),
            Team.id == foreign(Game.team2_id)
            ),
            viewonly=True,
            )
            users = relationship("User", secondary='teams_users', back_populates="teams")


            You could also make primaryjoin a string containing the expression now being executed in a lambda, so 'or_(Team.id == foreign(Game.team1_id), Team.id == foreign(Game.team2_id))'.



            Again, no back_populates, this type of relationship can't automatically update relationships between loaded objects. If you need to see these relationships reflected before committing, you'll need to issue a session flush. I also added viewonly=True, because you can't map mutations to the Team.games list to updates in the database (what would adding a new game to the list mean, that this team is team 1 or team 2?).



            You may want to add a custom constraint table to ensure that games never take place between the same team on both sides:



            class Game(Base):
            # ...
            __table_args__ = (
            CheckConstraint(team1_id != team2_id, name='different_teams'),
            )


            A quick demonstration of the relationships:



            from itertools import combinations

            engine = create_engine('sqlite:///:memory:', echo=False)
            Base.metadata.create_all(engine)
            session = sessionmaker(bind=engine)()

            teams = [Team() for _ in range(3)]
            session.add_all(teams)
            user = User(id=42, teams=teams)
            session.add(user)

            games = [Game(team1=t1, team2=t2) for t1, t2 in combinations(teams, 2)]
            session.add_all(games)
            session.commit()

            for team in user.teams:
            print('Team:', team.id, 'games:', [g.id for g in team.games])
            for game in session.query(Game):
            print(f'Game game.id: team game.team1.id vs game.team2.id')


            which outputs:



            Team: 2 games: [1, 3]
            Team: 1 games: [1, 2]
            Team: 3 games: [2, 3]
            Game 1: team 1 vs 2
            Game 2: team 1 vs 3
            Game 3: team 2 vs 3





            share|improve this answer





























              2














              To define the relationship between a game and the two teams that play in it, you need to only give the games table foreign keys; a team can play in multiple games, a one-to-many relationship; remove the games_id column altogether. The exception you got is a bit of a red herring, but it fails to properly configure the foreign_keys='games.id' argument in a relationship that doesn't need that foreign key.



              The relationship configuration on the Team class is a little tricky here as the Team.games attribute would have to relate to either foreign key. This is covered in the documentation under Handling Multiple Join Paths; you were almost there but there is no uselist parameter needed here:



              class Game(Base):
              __tablename__ = 'games'
              id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
              team1_id = Column(Integer, ForeignKey('teams.id'))
              team2_id = Column(Integer, ForeignKey('teams.id'))
              team1 = relationship("Team", foreign_keys=team1_id)
              team2 = relationship("Team", foreign_keys=team2_id)


              Note that I omitted the back_populates references here, because two relationships updating a single relationship on the other site leads one or the other of the two foreign keys being updated with the other value, leading to a game between the same team on either side!



              The inverse relationship attribute, Team.games, requires a custom primaryjoin because you are looking for games where either team1_id or team2_id is the foreign key pointing back. Use the foreign() annotation to help SQLAlchemy determine when to update the relationship (it'll watch for the foreign key changes), and use a lambda to defer resolving the columns:



              class Team(Base):
              __tablename__ = 'teams'
              id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
              # game_id = Column(Integer, ForeignKey('games.c.id'), nullable=False)
              games = relationship(
              "Game",
              primaryjoin=lambda: or_(
              Team.id == foreign(Game.team1_id),
              Team.id == foreign(Game.team2_id)
              ),
              viewonly=True,
              )
              users = relationship("User", secondary='teams_users', back_populates="teams")


              You could also make primaryjoin a string containing the expression now being executed in a lambda, so 'or_(Team.id == foreign(Game.team1_id), Team.id == foreign(Game.team2_id))'.



              Again, no back_populates, this type of relationship can't automatically update relationships between loaded objects. If you need to see these relationships reflected before committing, you'll need to issue a session flush. I also added viewonly=True, because you can't map mutations to the Team.games list to updates in the database (what would adding a new game to the list mean, that this team is team 1 or team 2?).



              You may want to add a custom constraint table to ensure that games never take place between the same team on both sides:



              class Game(Base):
              # ...
              __table_args__ = (
              CheckConstraint(team1_id != team2_id, name='different_teams'),
              )


              A quick demonstration of the relationships:



              from itertools import combinations

              engine = create_engine('sqlite:///:memory:', echo=False)
              Base.metadata.create_all(engine)
              session = sessionmaker(bind=engine)()

              teams = [Team() for _ in range(3)]
              session.add_all(teams)
              user = User(id=42, teams=teams)
              session.add(user)

              games = [Game(team1=t1, team2=t2) for t1, t2 in combinations(teams, 2)]
              session.add_all(games)
              session.commit()

              for team in user.teams:
              print('Team:', team.id, 'games:', [g.id for g in team.games])
              for game in session.query(Game):
              print(f'Game game.id: team game.team1.id vs game.team2.id')


              which outputs:



              Team: 2 games: [1, 3]
              Team: 1 games: [1, 2]
              Team: 3 games: [2, 3]
              Game 1: team 1 vs 2
              Game 2: team 1 vs 3
              Game 3: team 2 vs 3





              share|improve this answer



























                2












                2








                2







                To define the relationship between a game and the two teams that play in it, you need to only give the games table foreign keys; a team can play in multiple games, a one-to-many relationship; remove the games_id column altogether. The exception you got is a bit of a red herring, but it fails to properly configure the foreign_keys='games.id' argument in a relationship that doesn't need that foreign key.



                The relationship configuration on the Team class is a little tricky here as the Team.games attribute would have to relate to either foreign key. This is covered in the documentation under Handling Multiple Join Paths; you were almost there but there is no uselist parameter needed here:



                class Game(Base):
                __tablename__ = 'games'
                id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
                team1_id = Column(Integer, ForeignKey('teams.id'))
                team2_id = Column(Integer, ForeignKey('teams.id'))
                team1 = relationship("Team", foreign_keys=team1_id)
                team2 = relationship("Team", foreign_keys=team2_id)


                Note that I omitted the back_populates references here, because two relationships updating a single relationship on the other site leads one or the other of the two foreign keys being updated with the other value, leading to a game between the same team on either side!



                The inverse relationship attribute, Team.games, requires a custom primaryjoin because you are looking for games where either team1_id or team2_id is the foreign key pointing back. Use the foreign() annotation to help SQLAlchemy determine when to update the relationship (it'll watch for the foreign key changes), and use a lambda to defer resolving the columns:



                class Team(Base):
                __tablename__ = 'teams'
                id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
                # game_id = Column(Integer, ForeignKey('games.c.id'), nullable=False)
                games = relationship(
                "Game",
                primaryjoin=lambda: or_(
                Team.id == foreign(Game.team1_id),
                Team.id == foreign(Game.team2_id)
                ),
                viewonly=True,
                )
                users = relationship("User", secondary='teams_users', back_populates="teams")


                You could also make primaryjoin a string containing the expression now being executed in a lambda, so 'or_(Team.id == foreign(Game.team1_id), Team.id == foreign(Game.team2_id))'.



                Again, no back_populates, this type of relationship can't automatically update relationships between loaded objects. If you need to see these relationships reflected before committing, you'll need to issue a session flush. I also added viewonly=True, because you can't map mutations to the Team.games list to updates in the database (what would adding a new game to the list mean, that this team is team 1 or team 2?).



                You may want to add a custom constraint table to ensure that games never take place between the same team on both sides:



                class Game(Base):
                # ...
                __table_args__ = (
                CheckConstraint(team1_id != team2_id, name='different_teams'),
                )


                A quick demonstration of the relationships:



                from itertools import combinations

                engine = create_engine('sqlite:///:memory:', echo=False)
                Base.metadata.create_all(engine)
                session = sessionmaker(bind=engine)()

                teams = [Team() for _ in range(3)]
                session.add_all(teams)
                user = User(id=42, teams=teams)
                session.add(user)

                games = [Game(team1=t1, team2=t2) for t1, t2 in combinations(teams, 2)]
                session.add_all(games)
                session.commit()

                for team in user.teams:
                print('Team:', team.id, 'games:', [g.id for g in team.games])
                for game in session.query(Game):
                print(f'Game game.id: team game.team1.id vs game.team2.id')


                which outputs:



                Team: 2 games: [1, 3]
                Team: 1 games: [1, 2]
                Team: 3 games: [2, 3]
                Game 1: team 1 vs 2
                Game 2: team 1 vs 3
                Game 3: team 2 vs 3





                share|improve this answer















                To define the relationship between a game and the two teams that play in it, you need to only give the games table foreign keys; a team can play in multiple games, a one-to-many relationship; remove the games_id column altogether. The exception you got is a bit of a red herring, but it fails to properly configure the foreign_keys='games.id' argument in a relationship that doesn't need that foreign key.



                The relationship configuration on the Team class is a little tricky here as the Team.games attribute would have to relate to either foreign key. This is covered in the documentation under Handling Multiple Join Paths; you were almost there but there is no uselist parameter needed here:



                class Game(Base):
                __tablename__ = 'games'
                id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
                team1_id = Column(Integer, ForeignKey('teams.id'))
                team2_id = Column(Integer, ForeignKey('teams.id'))
                team1 = relationship("Team", foreign_keys=team1_id)
                team2 = relationship("Team", foreign_keys=team2_id)


                Note that I omitted the back_populates references here, because two relationships updating a single relationship on the other site leads one or the other of the two foreign keys being updated with the other value, leading to a game between the same team on either side!



                The inverse relationship attribute, Team.games, requires a custom primaryjoin because you are looking for games where either team1_id or team2_id is the foreign key pointing back. Use the foreign() annotation to help SQLAlchemy determine when to update the relationship (it'll watch for the foreign key changes), and use a lambda to defer resolving the columns:



                class Team(Base):
                __tablename__ = 'teams'
                id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
                # game_id = Column(Integer, ForeignKey('games.c.id'), nullable=False)
                games = relationship(
                "Game",
                primaryjoin=lambda: or_(
                Team.id == foreign(Game.team1_id),
                Team.id == foreign(Game.team2_id)
                ),
                viewonly=True,
                )
                users = relationship("User", secondary='teams_users', back_populates="teams")


                You could also make primaryjoin a string containing the expression now being executed in a lambda, so 'or_(Team.id == foreign(Game.team1_id), Team.id == foreign(Game.team2_id))'.



                Again, no back_populates, this type of relationship can't automatically update relationships between loaded objects. If you need to see these relationships reflected before committing, you'll need to issue a session flush. I also added viewonly=True, because you can't map mutations to the Team.games list to updates in the database (what would adding a new game to the list mean, that this team is team 1 or team 2?).



                You may want to add a custom constraint table to ensure that games never take place between the same team on both sides:



                class Game(Base):
                # ...
                __table_args__ = (
                CheckConstraint(team1_id != team2_id, name='different_teams'),
                )


                A quick demonstration of the relationships:



                from itertools import combinations

                engine = create_engine('sqlite:///:memory:', echo=False)
                Base.metadata.create_all(engine)
                session = sessionmaker(bind=engine)()

                teams = [Team() for _ in range(3)]
                session.add_all(teams)
                user = User(id=42, teams=teams)
                session.add(user)

                games = [Game(team1=t1, team2=t2) for t1, t2 in combinations(teams, 2)]
                session.add_all(games)
                session.commit()

                for team in user.teams:
                print('Team:', team.id, 'games:', [g.id for g in team.games])
                for game in session.query(Game):
                print(f'Game game.id: team game.team1.id vs game.team2.id')


                which outputs:



                Team: 2 games: [1, 3]
                Team: 1 games: [1, 2]
                Team: 3 games: [2, 3]
                Game 1: team 1 vs 2
                Game 2: team 1 vs 3
                Game 3: team 2 vs 3






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Mar 7 at 17:51

























                answered Mar 7 at 15:55









                Martijn Pieters♦Martijn Pieters

                720k14025172323




                720k14025172323





























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid …


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55047510%2ftable-object-has-no-attribute-id-on-sqlalchemy-relation%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Thal And Out Agency railway station See also References External links Navigation menuOfficial Web Site of Pakistan RailwaysArchivedOfficial Web Site of Pakistan Railwayseeexpanding ite

                    Posting a File and Associated Data to a RESTful WebService preferably as JSON2019 Community Moderator ElectionREST URI convention - Singular or plural name of resource while creating itUploading both data and files in one form using Ajax?How do I upload a file with metadata using a REST web service?REST API - file (ie images) processing - best practicesSpring: JSON data and file in the same requestREST API Put large dataPosting a file and JSON data to Spring rest serviceRESTful Web Service Upload/Download Large Data With JSONREST API Design sending JSON data and a file to the api in same requestPost JSONArray to REST servicePUT vs. POST in RESTParsing values from a JSON file?JavaScript/jQuery to download file via POST with JSON dataHow do I upload a file with metadata using a REST web service?How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?Separate REST JSON API server and client?what's the correct way to send a file from REST web service to client?How do I write JSON data to a file?What is “406-Not Acceptable Response” in HTTP?REST API - file (ie images) processing - best practices

                    How can I change the color of pagination dots of UIPageControl?How to change UIPageControl dotsIs there a way to change page indicator dots colorCustomize dot with image of UIPageControl at index 0 of UIPageControlNo visible @interface for 'NSObject<PageControlDelegate>' declares the selector 'pageControlPageDidChange:'How to change the color of pagination dots in UIPageControl with a different color per pagepagecontrol indicator custom image instead of DefaultChanging the colour of UIPageControl dots in MonoTouchpagecontrol selectable page visibility color?Alternative way to load ViewControllers on a UIPageControlHow to set only layer.border-color for UIpage control dots in swiftHow can I develop for iPhone using a Windows development machine?How to change the name of an iOS app?UITableView - change section header coloruipagecontrol indicator(dot)issueCustom UIPageControl dots color not changingchange the interspace between UIPageControl dotsHow to change Status Bar text color in iOSHow can I change image tintColor in iOS and WatchKitUIPageControl dots with larger space in between each dotsHow to change the color of pagination dots in UIPageControl with a different color per page