2009-08-28 16 views
1

SQLAlchemyを使用してバルク挿入/更新を実行しようとしています。ここでは、スニペットです:INSERT IGNOREを使用したSQLAlchemyセッションクエリ

for od in clist: 
    where = and_(Offer.network_id==od['network_id'], 
       Offer.external_id==od['external_id']) 
    o = session.query(Offer).filter(where).first() 
    if not o: 
     o = Offer() 
    o.network_id = od['network_id'] 
    o.external_id = od['external_id'] 
    o.title = od['title'] 
    o.updated = datetime.datetime.now() 
    payout = od['payout'] 
    countrylist = od['countries'] 
    session.add(o) 
    session.flush() 

    for country in countrylist: 
     c = session.query(Country).filter(Country.name==country).first() 
     where = and_(OfferPayout.offer_id==o.id, 
        OfferPayout.country_name==country) 
     opayout = session.query(OfferPayout).filter(where).first() 
     if not opayout: 
      opayout = OfferPayout() 
     opayout.offer_id = o.id 
     opayout.payout = od['payout'] 
     if c: 
      opayout.country_id = c.id 
      opayout.country_name = country 
     else: 
      opayout.country_id = 0 
      opayout.country_name = country 
     session.add(opayout) 

    session.flush() 

それは私の問題は、ここで触れたように、見えますhttp://www.mail-archive.com/[email protected]/msg05983.htmlが、私はセッションのクエリオブジェクトと「テキスト句」を使用する方法がわからないと多くを見つけることができませんでした(けれども確かに私は私が検索したいと思うほどの時間はなかった)。

私はSQLAlchemyのに新たなんだと私はそれが重複キーの例外をスローするという事実以外のコード内のいくつかの問題があります想像します。たとえば、clistを繰り返し実行するたびにフラッシュを実行します(ただし、その後のOfferPayout挿入に使用されるo.id値を取得する方法はわかりません)。

これらの問題に関するガイダンスは高く評価されています。

+0

OK、私は上記のコードは(NETWORK_ID、external_idにしてきたはずです)external_idに一意のインデックスを持つことによって引き起こされたINSERT/UPDATEの一部と重複キーエラーを処理し、実際にあることに気づきました。とにかく、私はそれをやっているやり方が今や総体的に感じられるように、上記をどのように改善できるかについてはまだ不思議です。 ORMでテキスト節を使用することについても聞きたいです。 –

答えて

2

これらの作業を行う方法は、session.merge()で行います。

オブジェクトの関連プロパティも使用する必要があります。したがって、上記のoはo.offerpayoutを持ち、これはオブジェクトのリストで、offerpayoutには関連する国オブジェクトであるofferpayout.countryプロパティがあります。

したがって、上記のこれは、限りすべてのプライマリキーが(すなわち、国のテーブルには、名前の主キーを持っている)正しいとして動作するはず

for od in clist: 

    o = Offer() 
    o.network_id = od['network_id'] 
    o.external_id = od['external_id'] 
    o.title = od['title'] 
    o.updated = datetime.datetime.now() 
    payout = od['payout'] 
    countrylist = od['countries'] 

    for country in countrylist: 
     opayout = OfferPayout() 
     opayout.payout = od['payout'] 
     country_obj = Country() 
     country_obj.name = country 
     opayout.country = country_obj 

     o.offerpayout.append(opayout) 

    session.merge(o) 
    session.flush() 

ようになります。 Mergeは基本的にプライマリキーをチェックし、プライマリキーが存在する場合はオブジェクトをデータベースにマージします(ジョインをカスケードします)。

関連する問題