Запрос сеанса SQLAlchemy с INSERT IGNORE - PullRequest
1 голос
/ 28 августа 2009

Я пытаюсь сделать массовую вставку / обновление с помощью 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 (но я не знаю, как еще получить значение o.id, которое используется в последующих вставках OfferPayout).

Руководство по любому из этих вопросов очень ценится.

1 Ответ

2 голосов
/ 29 августа 2009

То, как вы должны делать эти вещи, с помощью 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()

Это должно работать, пока все первичные ключи верны (то есть таблица страны имеет первичный ключ имени). Слияние по существу проверяет первичные ключи и, если они есть, объединяет ваш объект с одним в базе данных (он также будет каскадно объединяться).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...