我有以下模型(我还需要添加一些适当的验证):
class Participant(db.Model):
player_id = db.Column(db.Integer, db.ForeignKey('player.id'),
primary_key=True)
game_id = db.Column(db.Integer, db.ForeignKey('game.id'), primary_key=True)
winner = db.Column(db.Boolean)
class Player(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
avatar = db.Column(db.String(120))
skill = db.Column(db.Integer)
def __repr__(self):
return '<User %r>' % (self.name)
class Game(db.Model):
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime, default=datetime.datetime.utcnow)
loser_score = db.Column(db.Integer)
loser = db.relationship('Player',
secondary=Participant.__table__,
secondaryjoin=and_(
Player.id == Participant.player_id,
Participant.winner == False))
winner = db.relationship('Player',
secondary=Participant.__table__,
secondaryjoin=and_(
Player.id == Participant.player_id,
Participant.winner == True))
def __repr__(self):
return '<Game %r>' % (self.id)
当我检索数据时,这些功能很棒。当我插入一个Game对象时,它会忽略“赢家”。参与者表中的字段并生成以下SQL语句:
INFO:sqlalchemy.engine.base.Engine:
INSERT INTO game (date, loser_score) VALUES (?, ?)
('2015-02-13 19:31:04.804182', 15)
INSERT INTO participant (player_id, game_id) VALUES (?, ?)
(2, 2)
INSERT INTO participant (player_id, game_id) VALUES (?, ?)
(1, 2)
我希望它会产生:
INFO:sqlalchemy.engine.base.Engine:
INSERT INTO game (date, loser_score) VALUES (?, ?)
('2015-02-13 19:31:04.804182', 15)
INSERT INTO participant (player_id, game_id, winner) VALUES (?, ?, 0)
(2, 2)
INSERT INTO participant (player_id, game_id, winner) VALUES (?, ?, 1)
(1, 2)
有谁知道为什么会这样?
答案 0 :(得分:0)
你不能sqlalchemy
能够处理开箱即用的案件。下面的代码是我在这种情况下使用的代码:
class Player(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
avatar = db.Column(db.String(120))
skill = db.Column(db.Integer)
class Participant(db.Model):
player_id = db.Column(db.Integer, db.ForeignKey('player.id'),
primary_key=True)
game_id = db.Column(db.Integer, db.ForeignKey('game.id'), primary_key=True)
winner = db.Column(db.Boolean)
# relationships
player = db.relationship('Player')
class Game(db.Model):
id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime, default=datetime.datetime.utcnow)
loser_score = db.Column(db.Integer)
# relationships
game_players = db.relationship(
'Participant',
collection_class=attribute_mapped_collection("winner"),
cascade="all, delete-orphan",
backref="game",
)
# this allows usage like: my_game.player[True/False] = my_player
players = association_proxy(
'game_players', 'player',
creator=lambda win, pla: Participant(winner=win, player=pla),
)
# winner: an alias to self.players[True]
@property
def winner(self):
return self.players.get(True)
@winner.setter
def winner(self, value):
self.players[True] = value
@winner.deleter
def winner(self):
del self.players[True]
# loser: an alias to self.players[False]
@property
def loser(self):
return self.players.get(False)
@loser.setter
def loser(self, value):
self.players[False] = value
@loser.deleter
def loser(self):
del self.players[False]
允许您使用如下代码:
g1 = Game(...)
g1.players[True] = playerA
g1.players[False] = playerB
并且属性获胜者/输家甚至喜欢:
g1 = Game(...)
g1.winner = playerA
g1.loser = playerB
有关attribute_mapped_collection
及其用法的更多信息,请阅读Proxying to Dictionary Based Collections。