我已宣布以下模型:
from sqlalchemy import (
Column,
Table,
Integer,
Date,
String,
ForeignKey,
)
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import relationship, backref
engine = create_engine('sqlite:///data.sqlite')
DBSession = sessionmaker(bind=engine)
Base = declarative_base()
lineup = Table('lineups', Base.metadata,
Column('match_id', Integer, ForeignKey('data.id')),
Column('player_id', Integer, ForeignKey('players.id')))
class Match(Base):
__tablename__ = 'data'
id = Column(Integer, primary_key=True)
date = Column(Date)
tournament = Column(String)
team1 = Column(String)
team2 = Column(String)
team1_lineup = relationship('Player', secondary=lineup)
team2_lineup = relationship('Player', secondary=lineup)
best_of = Column(Integer)
maps = relationship('Map')
score = Column(String)
class Map(Base):
__tablename__ = 'maps'
id = Column(Integer, primary_key=True)
match = Column(Integer, ForeignKey('data.id'))
name = Column(String)
score = Column(String)
class Player(Base):
__tablename__ = 'players'
id = Column(Integer, primary_key=True)
nickname = Column(String)
team = Column(String)
我以这种方式创建新的Match
对象:
match = Match(...) # all kwargs except team1_lineup and team2_lineup
p1 = Player(id=1, nickname='p1', team='team')
p2 = Player(id=2, nickname='p2', team='team')
p3 = Player(id=3, nickname='p2', team='team')
match.team1_lineup.append(p1)
match.team2_lineup.append(p2)
match.team2_lineup.append(p3)
提交新对象后,我查询它。
>>> from hltv.models import Match, DBSession
>>> s = DBSession()
>>> m = s.query(Match).first()
>>> m.team1_lineup
[<hltv.models.Player object at 0x7f1a93009d10>, <hltv.models.Player object at 0x7f1a93009d90>, <hltv.models.Player object at 0x7f1a93009e10>]
>>> m.team2_lineup
[<hltv.models.Player object at 0x7f1a93009d10>, <hltv.models.Player object at 0x7f1a93009d90>, <hltv.models.Player object at 0x7f1a93009e10>]
问题是m.team1_lineup
和m.team2_lineup
是相同的。我怎么解决这个问题?
另外,如何为每个阵容分配ID(具有相同玩家的阵容应该具有相同的ID)?
答案 0 :(得分:2)
我设法解决了我的问题。我必须在阵容中添加ID(我已将其重命名为Team),并通过为这些团队提供两个不同的ID来指定如何连接表。 André发布的另一种解决方案。
以下是代码:
from sqlalchemy import (
Column,
Table,
Integer,
Date,
String,
ForeignKey,
)
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref
engine = create_engine('sqlite:///data.sqlite')
DBSession = sessionmaker(bind=engine)
Base = declarative_base()
class Match(Base):
__tablename__ = 'data'
id = Column(Integer, primary_key=True)
date = Column(Date)
tournament = Column(String)
best_of = Column(Integer)
score = Column(String)
maps = relationship('Map')
team1_id = Column(ForeignKey('team.id'))
team2_id = Column(ForeignKey('team.id'))
team1 = relationship('Team', primaryjoin='Match.team1_id == Team.id')
team2 = relationship('Team', primaryjoin='Match.team2_id == Team.id')
class Map(Base):
__tablename__ = 'map'
id = Column(Integer, primary_key=True)
match = Column(Integer, ForeignKey('data.id'))
name = Column(String)
score = Column(String)
lineup = Table('lineup',
Base.metadata,
Column('player_id', Integer, ForeignKey('player.id')),
Column('team_id', Integer, ForeignKey('team.id')))
class Player(Base):
__tablename__ = 'player'
id = Column(Integer, primary_key=True)
nickname = Column(String)
class Team(Base):
__tablename__ = 'team'
id = Column(Integer, primary_key=True)
name = Column(String)
players = relationship('Player', secondary=lineup, backref='teams')
答案 1 :(得分:0)
我在关系中有一些建议:
我的建议是更改多对多的某些模型,例如:
from sqlalchemy import (
Column,
Table,
Integer,
Date,
String,
ForeignKey,
)
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import relationship, backref
engine = create_engine('sqlite:///data.sqlite')
DBSession = sessionmaker(bind=engine)
Base = declarative_base()
lineup = Table('lineups', Base.metadata,
Column('team_id', Integer, ForeignKey('teams.id')),
Column('player_id', Integer, ForeignKey('players.id')))
class Team(Base):
__tablename__ = 'teams'
id = Column(Integer, primary_key=True,autoincrement= True)
name = Column(String)
team_lineup = relationship('Player',secondary=lineup)
match_team = Table('match_teams', Base.metadata,
Column('match_id', Integer, ForeignKey('matches.id')),
Column('team_id', Integer, ForeignKey('teams.id')))
class Match(Base):
__tablename__ = 'matches'
id = Column(Integer, primary_key=True,autoincrement= True)
date = Column(Date)
tournament = Column(String)
team = relationship('Team',secondary=match_team)
best_of = Column(Integer)
maps = relationship('Map')
score = Column(String)
class Map(Base):
__tablename__ = 'maps'
id = Column(Integer, primary_key=True,autoincrement= True)
match = Column(Integer, ForeignKey('matches.id'))
name = Column(String)
score = Column(String)
class Player(Base):
__tablename__ = 'players'
id = Column(Integer, primary_key=True,autoincrement= True)
nickname = Column(String)
创建objets ......
s = DBSession()
Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
t1 = Team(name="t1")
t2 = Team(name="t2")
p1 = Player()
p2 = Player()
p3 = Player()
s.add(p1)
s.add(p2)
s.add(p3)
t1.team_lineup.append(p1)
t2.team_lineup.append(p2)
t2.team_lineup.append(p3)
s.add(t1)
s.add(t2)
m = Match()
m.tournament="xpto"
m.team.append(t1)
m.team.append(t2)
s.add(m)
s.commit()
之后,你可以看到阵容与你的期望一样:
>>> m = s.query(Match).first()
>>> for t in m.team:
... print t.team_lineup
...
[<__main__.Player object at 0x10b57c890>]
[<__main__.Player object at 0x10b57c910>, <__main__.Player object at 0x10b57c990>]
在这种情况下,您可以拥有&#34; n&#34;每场比赛的球队。我不知道你所管理的运动是否有可能。