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/sqlalchemy@googlegroups.com/msg05983.html,但我不知道如何在会话查询对象中使用“文本子句”,而且我找不到太多相关的信息(不过老实说,我也没有太多时间去搜索)。
我对SQLAlchemy还很陌生,我想代码中可能还有其他问题,除了在遇到重复键时会抛出异常。例如,我在每次处理clist时都进行一次flush(但我不知道还有什么其他方法可以获取后续OfferPayout插入中使用的o.id值)。
对于这些问题的任何指导都非常感谢。
1 个回答
3
你应该用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的作用就是检查主键,如果主键存在,它会把你的对象和数据库里的对象合并(同时也会处理相关的连接)。