Как выполнить массовое обновление с использованием ядра sqlalchemy? Различные столбцы обновляются для каждой записи

Хотя я могу обновить несколько значений, если я знаю столбцы заранее, у меня возникают проблемы с созданием массового обновления, если не нужно жестко кодировать значения столбцов.

Учтите следующее:

stmt = task_table.update() \
    .where(task_table.c.id == bindparam('idx')) \
    .values(bindparam('values'))
vals = [{'idx': task.idx, 
         'values':{'queueStatus': task.queue_status, 'detail':str(task.idx)}}
        for task in actions]

connection.execute(stmt, vals)
connection.commit()

Это дает ошибку AttributeError: Neither 'BindParameter' object nor 'Comparator' object has an attribute 'items', в values()

Я мог бы изменить это на что-то вроде:

stmt = task_table.update() \
    .where(task_table.c.id == bindparam('idx')) \
    .values({queueStatus=bindparam('values'), detail=bindparam('detail')})
vals = [{'idx': task.idx, 
         'values':task.queue_status, 'detail':str(task.idx)}
        for task in actions]

connection.execute(stmt, vals)
connection.commit()

Однако это потребует от меня всегда указывать все столбцы, даже если я не хочу обновлять эти столбцы.

1 ответ

Единственное отличие, которое я вижу из вашего примера, состоит в том, что вы пытаетесь распаковать несколько значений, не указывая, какой именно столбец вы хотите обновить, а также обратите внимание на ограниченные имена, используемые для bindparams, что-то вроде этого должно работать:

stmt = (
    task_table.update()
        .where(task_table.c.id == bindparam('_idx'))
        .values(
        queueStatus=bindparam('_queue_status'),
        detail=bindparam('_detail')
    )
)
vals = [
    {
        '_idx': task.idx,
        '_queue_status': task.queue_status,
        '_detail': str(task.idx),
    }
    for task in actions
]

connection.execute(stmt, vals)
connection.commit()

Это описано в документации по sqlalchemy:

Другие вопросы по тегам