Search code examples
pythonpython-3.xpymssql

Execution Order of pymssql's cursor.executemany()


Does cursor.executemany(...) of the pymssql module have a guaranteed execution order?

import pymssql

# Example retrieved from: http://pymssql.org/en/stable/pymssql_examples.html

# ...
conn = pymssql.connect(server, user, password, "tempdb")
cursor = conn.cursor()

# ...
cursor.executemany(
    "INSERT INTO persons VALUES (%d, %s, %s)",
    [(1, 'John Smith', 'John Doe'),
     (2, 'Jane Doe', 'Joe Dog'),
     (3, 'Mike T.', 'Sarah H.')])
conn.commit()
conn.close()

See also: http://pymssql.org/en/stable/pymssql_examples.html

In a real scenario, I require to update values in a specific order (I have an ordered array of tuples) and would like to avoid execute those updates one by one with cursor.execute(...).


Looks like PEP 249 is very open with its requirement...

Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters.

Modules are free to implement this method using multiple calls to the .execute() method or by using array operations to have the database process the sequence as a whole in one call.

https://www.python.org/dev/peps/pep-0249/#executemany

That raises another question... Does pymssql's implementation of PEP 249 execute them anyway one by one with cursor.execute(...)?


Solution

  • def executemany(self, operation, params_seq):
        self.description = None
        rownumber = 0
        for params in params_seq:
            self.execute(operation, params)
            # support correct rowcount across multiple executes
            rownumber += self._rownumber
        self._rownumber = rownumber
    

    According to the source code, the executemany function just iterate the given sequence and call execute.

    ref: https://github.com/pymssql/pymssql/blob/891b20e29e4e247c17b202e8e34e5c739b6090ef/src/pymssql.pyx#L472