SQLAlchemy中所有行的有效更新

时间:2019-10-22 22:50:29

标签: python python-3.x postgresql sqlalchemy

我目前正在尝试通过基于同一行中另一列images的值设置一列source_images的值来更新表中的所有行。

for row in Cars.query.all():
    # Generate a list of strings
    images = [s for s in row.source_images if 'example.com/' in s]

    # Column 'images' being updated is a sqlalchemy.dialects.postgresql.ARRAY(Text())
    Cars.query.filter(Cars.id == row.id).update({'images': images}) 

db_session.commit()

问题:这似乎确实很慢,尤其是当应用于10万以上的行时。有没有更有效的方式来更新行?

类似的问题:

#1:这个问题涉及通过增加值来更新所有行。

模型类定义:cars.py

from sqlalchemy import *
from sqlalchemy.dialects import postgresql
from ..Base import Base

class Car(Base):
    __tablename__ = 'cars'
    id = Column(Integer, primary_key=True)
    images = Column(postgresql.ARRAY(Text))
    source_images = Column(postgresql.ARRAY(Text))

1 个答案:

答案 0 :(得分:1)

您可以将操作转到数据库,而不是分别获取和更新每一行:

from sqlalchemy import select, column, func

source_images = select([column('i')]).\
    select_from(func.unnest(Car.source_images).alias('i')).\
    where(column('i').contains('example.com/'))

source_images = func.array(source_images)

Car.query.update({Car.images: source_images},
                 synchronize_session=False)

相关的子查询取消嵌套源图像,选择与条件匹配的图像,然后ARRAY() constructor形成新的图像阵列。

或者,您可以使用array_agg()

source_images = select([func.array_agg(column('i'))]).\
    select_from(func.unnest(Car.source_images).alias('i')).\
    where(column('i').contains('example.com/'))