两个列使用SqlAlchemy连接同一个表

时间:2015-08-04 08:49:36

标签: sqlite python-3.x flask flask-sqlalchemy

我使用 SqlAlchemy Flask 中构建与运动相关的应用程序。我有一个游戏表,其中home_teamaway_team都加入团队表。

我希望能够声明 Team 表和 Game 表之间的关系,但我收到错误

  

Could not determine join condition between parent/child tables on relationship Team.games - there are multiple foreign key paths linking the tables. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.

模型声明如下所示:

class Team(db.Model):

    """Team model."""

    __tablename__ = "teams"

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    monkier = db.Column(db.String)
    town = db.Column(db.String)

    games = db.relationship('Game')

    def __init__(self):
           ......

class Game(db.Model):

    """Game model."""

    __tablename__ = "games"

    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.DateTime)
    ground_id = db.Column(db.Integer, db.ForeignKey('grounds.id'))
    round_id = db.Column(db.Integer, db.ForeignKey('rounds.id'))
    home_team_id = db.Column(db.Integer, db.ForeignKey('teams.id'))
    away_team_id = db.Column(db.Integer, db.ForeignKey('teams.id'))
    home_score = db.Column(db.String)
    away_score = db.Column(db.String)

    ground = db.relationship('Ground')
    round = db.relationship('Round')
    home_team = db.relationship('Team',
                                primaryjoin="Game.home_team_id == Team.id")
    away_team = db.relationship('Team',
                                primaryjoin="Game.away_team_id == Team.id")

    def __init__(self):
           ......

看起来我必须将foreign_keys关键字参数传递给关系,但我不知道如何做到这一点,因为它需要away_team_idhome_team_id

当然它也可能只是糟糕的数据库设计。

1 个答案:

答案 0 :(得分:4)

我认为您可以通过对模型进行一些调整来创建您正在寻找的关系。

class Team(db.Model):

    """Team model."""

    __tablename__ = "teams"

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    monkier = db.Column(db.String)
    town = db.Column(db.String)

    home_games = db.relationship('Game', foreign_keys='Game.home_team_id', backref='home_team', lazy='dynamic')
    away_games = db.relationship('Game', foreign_keys='Game.away_team_id', backref='away_team', lazy='dynamic')

    def __init__(self):
           ......

    @property
    def games(self):
        return self.home_games.union(self.away_games)

class Game(db.Model):

    """Game model."""

    __tablename__ = "games"

    id = db.Column(db.Integer, primary_key=True)
    date = db.Column(db.DateTime)
    ground_id = db.Column(db.Integer, db.ForeignKey('grounds.id'))
    round_id = db.Column(db.Integer, db.ForeignKey('rounds.id'))
    home_team_id = db.Column(db.Integer, db.ForeignKey('teams.id'))
    away_team_id = db.Column(db.Integer, db.ForeignKey('teams.id'))
    home_score = db.Column(db.String)
    away_score = db.Column(db.String)

    ground = db.relationship('Ground')
    round = db.relationship('Round')

    def __init__(self):
           ......

现在,您可以通过Team关系中定义的backref属性访问Team模型。

e.g。 game.away_teamgame.home_team

您还可以专门查询主页,客场或特定于球队的所有游戏。

all_home_games = team.home_games.all()
away_against_dodgers = team.away_games.filter_by(name='Dodgers').all()
some_date = DateTime(...)
all_games_before_date = team.games.filter(Game.date < some_date).all()