使用INSERT IGNORE进行SQLAlchemy会话查询

时间:2009-08-28 17:57:35

标签: python sqlalchemy

我正在尝试使用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/sqlalchemy@googlegroups.com/msg05983.html,但我不知道如何使用会话查询对象的“文本子句”并且找不到多少(尽管我没有找到)和我想搜索的时间一样多。

我是SQLAlchemy的新手,我想在代码中存在一些问题,除了它会在重复键上引发异常。例如,在每次clist迭代后执行刷新(但我不知道如何获得后续OfferPayout插入中使用的o.id值)。

非常感谢任何这些问题的指导。

1 个答案:

答案 0 :(得分: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基本上检查主键,如果它们在那里,则将对象与数据库中的对象合并(它也将级联连接)。