def update_all(engine, table, data, upsert=False):
data = ensure_list(data)<EOL>ins = table.insert()<EOL>upd = table.update()<EOL>pk_cols = OrderedDict()<EOL>for column in table._columns:<EOL><INDENT>if column.primary_key:<EOL><INDENT>pk_cols[column.name] = column<EOL><DEDENT><DEDENT>data_to_insert = list()<EOL>if len(pk_cols) >= <NUM_LIT:2>:<EOL><INDENT>for row in data:<EOL><INDENT>result = engine.execute(<EOL>upd.<EOL>where(<EOL>and_(<EOL>*[col == row[name] for name, col in pk_cols.items()]<EOL>)<EOL>).<EOL>values(**row)<EOL>)<EOL>if result.rowcount == <NUM_LIT:0>:<EOL><INDENT>data_to_insert.append(row)<EOL><DEDENT><DEDENT><DEDENT>elif len(pk_cols) == <NUM_LIT:1>:<EOL><INDENT>for row in data:<EOL><INDENT>result = engine.execute(<EOL>upd.<EOL>where(<EOL>[col == row[name] for name, col in pk_cols.items()][<NUM_LIT:0>]<EOL>).<EOL>values(**row)<EOL>)<EOL>if result.rowcount == <NUM_LIT:0>:<EOL><INDENT>data_to_insert.append(row)<EOL><DEDENT><DEDENT><DEDENT>else:  <EOL><INDENT>data_to_insert = data<EOL><DEDENT>if upsert:<EOL><INDENT>if len(data_to_insert):<EOL><INDENT>engine.execute(ins, data_to_insert)<EOL><DEDENT><DEDENT>
Update data by its primary_key column.

:type engine: Engine
:type table: Table
:type data: list
:type upsert: bool