2012-02-25 7 views
1

フラスコ内でFlaskとSQLAlchemyを使い始めたばかりです。フラスコ関係モデル複数存在する場合は取得または作成

ここでは例を使用して多対多の関係がありますhttp://docs.sqlalchemy.org/en/latest/orm/tutorial.html キーワードとタグについての部分にスクロールすると、これは私が取り組んでいることです。 これまで私の投稿に関連する新しいキーワードを挿入することができ、私は追加を使用しています。それは私が知っている間違っている。だから、次にユニークではないキーワードがブログ投稿に現れると、キーワードとの競合についてのエラーが発生します(キーワードは一意であると考えられます)。

私は正しい方法が何か他のものであることを知っています。何がわからない。私は get_or_create(キーワード)の例を見てきましたが、基本的にはキーワードでフィルタリングし、見つからなければ追加します。しかし、データサイズが大きくなるにつれてこれも間違っていると私は信じています。 (1回の挿入ですべてのセーブにいくつかの呼び出しがあります)。私はSQLAlchemyが自動的に複数の挿入を行う方法が大好きです。私はそれを残しておきたいが、この重複するキーの問題を避ける。

編集:SQLAlchemy docsが解決策を見つけましたが、エラーが発生しましたが説明があります。私は答えを加えました。

+0

btw私は関連モデルにappendを使用しています。このような。 post.keywords.append(Keyword( "foo"))次にcommitを呼び出します。 – Vangel

+0

モデルを投稿して実際のコードを追加できますか? – plaes

+0

投稿を更新しました。私は明らかに何もしませんし、何もしないマージ()のようなものを試しました。 2ページ目の読み込みは常にエラーを引き起こします。私はGameテーブルに存在しないゲーム(タグ)とusergames(存在しない場合)だけを追加したいと思います。 Ofcourse私はユーザーのゲームではなく、ゲームであるゲームを持っていない。その部分は問題ありません。 – Vangel

答えて

2

私は解決策を見つけ、試して何時間も過ごした後、私は間違っていました。

これは、SQLの錬金術の仕組みです。答えはマージです。

タグのリストをタグモデルとして作成します。プライマリキーが名前またはユニークなものである限り、存在するかどうかは関係ありません。

tags = [Tag('a1'),Tag('a2')] 

タグが既にDBにあるとしますが、私たちは本当に気にしません。私たちが望むのは、関連するデータが存在しない場合にのみ挿入することです。 SQLalchemyの機能は何ですか? 今度は、私たちが作ったすべてのタグのリストを含む投稿を作成します。 1つだけの場合は、それもリストです。

ので

new_post = Post('a great new post',post_tags=tags) 
db.session.merge(new_post) 
db.session.commit() 

私はフラスコの構文を使用していたが、考え方は同じです。セッションの外にモデルを作成していないことを確認してください。おそらく、あなたはそれをやろうとはしません。

これは実際にはシンプルでしたが、SQLAlchemyのドキュメントではこの例は言及されていませんでした。彼らは間違っているappend()を使用します。あなたが重複していないことを知っている新しいタグを作成するだけです。

希望します。

+2

merge()は、Tag()が主キーとして文字列コンテンツ "a1"、 "a2"、つまり自然な主キーを持っていた場合にのみ適切です。主キー。もっと一般的な "Xのユニークなオブジェクト"レシピはhttp://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObjectにあります。これは多少なりともチュートリアルの範囲外です。チュートリアルの中の "append()"の使い方は "間違った"ものではなく、多対多の関係がどのように働くかを示しています。チュートリアルの例では、キーワードにサロゲートpkがあるため、merge()は機能しません。 – zzzeek

関連する問題