我有两张桌子Foo和Bar。我刚刚在Bar表中添加了一个新列x
,必须使用Foo中的值填充
class Foo(Base):
__table__ = 'foo'
id = Column(Integer, primary_key=True)
x = Column(Integer, nullable=False)
class Bar(Base):
__table__ = 'bar'
id = Column(Integer, primary_key=True)
x = Column(Integer, nullable=False)
foo_id = Column(Integer, ForeignKey('foo.id'), nullable=False)
一种直接的方法是迭代Bar中的所有行,然后逐个更新它们,但这需要很长时间(Foo和Bar中有超过10万行)
for b, foo_x in session.query(Bar, Foo.x).join(Foo, Foo.id==Bar.foo_id):
b.x = foo_x
session.flush()
现在我想知道这是否是正确的方法 -
mappings = []
for b, foo_x in session.query(Bar, Foo.x).join(Foo, Foo.id==Bar.foo_id):
info = {'id':b.id, 'x': foo_x}
mappings.append(info)
session.bulk_update_mappings(Bar, mappings)
bulk_update_mappings
上的例子不多。文档建议
所有存在且不属于主键的键 应用于UPDATE语句的SET子句;主键 必需的值将应用于WHERE子句。
因此,在这种情况下id
将在WHERE
子句中使用,然后使用字典中的x
值进行更新吗?
答案 0 :(得分:9)
这种方法在使用方面是正确的。我唯一要改变的就是下面的内容
mappings = []
i = 0
for b, foo_x in session.query(Bar, Foo.x).join(Foo, Foo.id==Bar.foo_id):
info = {'id':b.id, 'x': foo_x}
mappings.append(info)
i = i + 1
if i % 10000 == 0:
session.bulk_update_mappings(Bar, mappings)
session.flush()
session.commit()
mappings[:] = []
session.bulk_update_mappings(Bar, mappings)
这样可以确保您没有太多数据挂在内存中,并且您不会一次性对数据库进行太大的插入