2013-03-06 10 views
1

Я использую SQLAlchemy здесь, пытаясь сделать пару таблиц и связать их, и у меня возникают проблемы с этим.SQLAlchemy Using relationship()

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

У меня есть это в одном файле, который я использую для создания таблиц. Затем в другом файле я использую функцию insert(), чтобы поместить значения в обе таблицы. Я думаю, что если у меня есть команда с espn_team_id 360, а затем я положил в несколько игр в игровом столе, которые имеют либо h_espn_id = 360, или a_espn_id = 360, я должен быть в состоянии сделать:

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

и его должен дать мне список всех команд для игр с ID 360. Но вместо этого я получаю эту ошибку

AttributeError: объект «NamedTuple» имеет атрибута 'игры

Что я недопонимание о SQLAlchemy или реляционных базах данных здесь?

ответ

0

Вот решение, которое я нашел, взял слишком много времени, чтобы понять это ...

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 
1

Во-первых, вам не нужно создавать еще один объект Table, так как он доступен как Team.__table__. В любом случае, вы можете просто запросить сопоставленный класс, например.

query = Session.query(Team).filter(Team.espn_team_id == 360) 
team360 = query.one() 
games = team360.games 

Обратитесь к документации по методам .one(), .first() и .all(): http://docs.sqlalchemy.org/en/latest/orm/query.html

+0

sayap благодаря для вашего поста и вашей первой точки. Второй момент - моя ошибка, я сейчас отредактирую его, я включил .first(), и это не сработает. Часы: печать session.query (а) .filter (acespn_team_id == 360) .first() игры Traceback (самый последний вызов последнего):. Файл "", строка 1, в AttributeError: объект «NamedTuple» не имеет атрибутов «игры» – appleLover

+0

, и я стараюсь делать это по-своему: from table_def import Team, Game >>> print session.query (Team) .filter (Team.espn_team_id == 360) .first(). игры [большое сообщение об ошибке] sqlalchemy.exc.InvalidRequestError: Один или несколько картографов не удалось инициализировать - невозможно продолжить инициализацию других картографов. Исходное исключение: Не удалось определить условие соединения между родительскими/дочерними таблицами в команде Team.games. Укажите выражение 'primaryjoin'. Если присутствует «вторичный», требуется также «secondaryjoin». – appleLover

+0

О, да, сопоставления классов неполны, так как у вас есть два внешних ключа между таблицами. Я думаю, вам нужно иметь команды Team.home_games' и 'Team.away_games'. – sayap