Como se señaló en un comentario a otra respuesta, T-SQL BULK INSERT
El comando solo funcionará si el archivo que se va a importar está en la misma máquina que la instancia de SQL Server o está en una ubicación de red SMB/CIFS que la instancia de SQL Server puede leer. Por lo tanto, puede que no sea aplicable en el caso de que el archivo de origen esté en un cliente remoto.
pyodbc 4.0.19 agregó una función Cursor#fast_executemany que puede ser útil en ese caso. fast_executemany
está "apagado" por defecto, y el siguiente código de prueba...
cnxn = pyodbc.connect(conn_str, autocommit=True)
crsr = cnxn.cursor()
crsr.execute("TRUNCATE TABLE fast_executemany_test")
sql = "INSERT INTO fast_executemany_test (txtcol) VALUES (?)"
params = [(f'txt{i:06d}',) for i in range(1000)]
t0 = time.time()
crsr.executemany(sql, params)
print(f'{time.time() - t0:.1f} seconds')
... tardó aproximadamente 22 segundos en ejecutarse en mi máquina de prueba. Simplemente agregando crsr.fast_executemany = True
...
cnxn = pyodbc.connect(conn_str, autocommit=True)
crsr = cnxn.cursor()
crsr.execute("TRUNCATE TABLE fast_executemany_test")
crsr.fast_executemany = True # new in pyodbc 4.0.19
sql = "INSERT INTO fast_executemany_test (txtcol) VALUES (?)"
params = [(f'txt{i:06d}',) for i in range(1000)]
t0 = time.time()
crsr.executemany(sql, params)
print(f'{time.time() - t0:.1f} seconds')
... redujo el tiempo de ejecución a poco más de 1 segundo.