2017-05-24 11 views
0

私は一連のユーザーと一連のゲームを持っていて、別のテーブル(名前: 'game_progress')でゲームを終了したかどうかを追跡します。私は、ユーザーが作成されるたびに、 'game_progress'テーブルに彼女のIDが自動的に入力され、使用可能なすべてのゲームに対して 'いいえ'が表示されます。 (彼女がレコードを作るためにゲームを始めるまで待つことができますが、私はこれを全く別の目的のために必要とします)。SQLAlchemyオブジェクトを作成するときのカスタム操作

私はafter_insert()イベントを使用してみました。しかし、私は 'game_progress'に挿入するユーザーのIDを取得できません。私はafter_flushを使用したくないです(たとえ私がそれをやる方法を見つけ出すことができます)。これは、ユーザ作成操作がそれほど頻繁に起こらないので、少し過度のことかもしれません。

class Game(db.Model): 

    __tablename__ = 'games' 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.Unicode(30)) 

class User(db.Model): 

    __tablename__ = 'users' 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.Unicode(30)) 

class GameProgress(db.Model): 

    __tablename__ = 'game_progress' 
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True) 
    game_id = db.Column(db.Integer, db.ForeignKey('games.id'), primary_key=True) 
    game_finished = db.Column(db.Boolean) 

@event.listens_for(User, "after_insert") 
def after_insert(mapper, connection, target): 
    progress_table = GameProgress.__table__ 
    user_id = target.id 
    connection.execute(
     progress_table.insert().\ 
      values(user_id=user_id, game_id=1, game_finished=0) 
    ) 

db.create_all() 
game = Game(name='Solitaire') 
db.session.add(game) 
db.session.commit() 
user = User(name='Alice') 
db.session.add(user) 
db.session.commit() 
+0

通常、DBトリガーを使用するか、新しいユーザーを作成するロジックに必要な追加データの作成を含めるだけです。つまり、ユーザーの作成を処理する関数を作成することを意味します。 –

答えて

0

あなたは、あなただけの関係を設定して、ユーザーのコンストラクタに関連するオブジェクトを作ることができる、全くトリガーやイベントリスナーと空想何もする必要はありません。あなたが関係を定義している限り(あなたは現在行っていない、あなたは外部キーを追加しただけです)、関連するオブジェクトを設定するためにIDを持つ必要はありません。あなたのコンストラクタはちょうどこのような何かを行うことができます。

class User(db.Model): def __init__(self, all_games, **kwargs): for k,v in kwargs.items(): setattr(self, k, v) for game in all_games: self.game_progresses.append(GameProgress(game=game, \ user=self, game_finished=False))

ユーザーをコミットすると、あなたはまたGameProgressオブジェクト、各ゲームの1のリストをコミットします。しかし、上記はあなたのすべてのオブジェクトに関係を設定することに依存します。それが終わっています一度

all_games = dbs.query(Game).all() new_user = User(all_games=all_games, name="Iain")

は、あなただけのGameProgressを追加することができます:あなたは、あなたのユーザーを作るときGameProgressクラスに以下の

game = relationship("Game", backref="game_progresses") user = relationship("User", backref="game_progresses")

を追加し、ユーザーにゲームのリストに渡す必要がありますオブジェクトをインストルメント済みのリストuser.game_progressesに追加すると、最初のコミットの前に何かをコミットする必要はありません。 SQLAはすべての関係を追跡します。基本的には、あなたが直接IDとぶち壊す必要があるときはいつでも、ORMの権利を使用しているかどうか自問自答してください。 SQLAのドキュメントに関するORMのチュートリアルはこれをうまく通り抜けます。あなたが望むことをやり遂げるために関係やバックレフに渡すことができるたくさんのオプションがあります。

+0

パーフェクト。 「あなたがIDと直接噛み合う必要があるときはいつでも、ORMの権利を使用しているかどうか自問してください。ありがとう! – contrariwise

関連する問題