2016-06-30 3 views
0

私は別のオブジェクトへの外部キーを持つオブジェクトを持っています。最初のオブジェクトをAとし、2番目のオブジェクトをBとしましょう。 A(integer id, integer b_id, integer some_data)として表現することができ、B(integer id, integer datum_one, integer datum_two)SQLAlchemyは、追加する前にオブジェクトを検索してマージします

datum_onedatum_two形として表現することができBでユニークな複合(私はこれは正しい用語だと思う - 私は同じ組み合わせとBのエントリでより多くを望んでいませんこれらのフィールドのうちの)。しかし、私はちょうどAからBに指すForeignKeyのidを参照したいと思う。それは、複合外来キーlike hereのようなものを行うのは面倒で冗長なようです。

私は同じdatum_onedatum_twoを持っているマッチングBため、私は私のデータベースにAを追加し、それ最初に検索し、そのような機能を持っていると思います。これが存在する場合は、データベース内の一致するエントリを使用し、それ以外の場合は、Bを表すテーブルに新しい行を追加します。

これを行う方法はありますか?私はソリューションがマージディレクティブと何か関係があると思われますが、この機能を正確に取得する方法がわかりません。

実際にはUNIQUEディレクティブを使用していた可能性がありますが、SQLAlchemyはユニークではうまくいきません - 私は基本的には独自のエラー処理を書く必要がありますが、SQLAlchemyこれにはよりエレガントな解決策があります。

+0

Mergeは主キーで動作するので、あなたを助けません。データム値に基づいて新しいBを選択または挿入するときは、データ値がありません。私は複合外来キーがどのようにこのケースでもあなたを助けてくれるかをかなり理解していません。あなたがしなければならないこと、すでに部分的にレイアウトしてしまったことは、データムに一意の制約を使用し、既存のデータを挿入または選択することです。どのようにSQLAlchemyがユニークな制約で「うまくいくか」正確にはいかないのですか? –

+0

これを[tag:sqlite]とタグ付けしたので、まずBに「INSERT OR IGNORE」してからBのIDを選択することができます。一意の制約違反があればそれを無視して、 。 –

+0

例えばSQLAlchemyのでは 'OR IGNORE'などのDB固有の機能を使用する方法については、[この質問と回答](http://stackoverflow.com/questions/2218304/sqlalchemy-insert-ignore)を参照してください。 'Session.merge'、プライマリキー、ユニーク制約については[Michael Bayerによるこの回答](https://groups.google.com/forum/#!topic/sqlalchemy/3UjRwQ0M8kk)も参照してください。 –

答えて

1

私はあなただけのデータベースにあなたのオブジェクトを挿入する前にこの身を扱うべきだと思います。ドキュメントから... http://docs.sqlalchemy.org/en/latest/core/events.html

from sqlalchemy import event 

# standard decorator style 
@event.listens_for(SomeSchemaClassOrObject, 'before_create') 
def receive_before_create(target, connection, **kw): 
    "listen for the 'before_create' event" 

    # ... (event handling logic) ... 
+0

ああ、私はこの解決策が好きです。私はすでにこれを処理するコードを書いていましたが、この特定のアプローチはよりクリーンかもしれません。 –

関連する問題