Быстрый способ конвертировать массив в кортеж / список в Python? - PullRequest
2 голосов
/ 11 октября 2011

Кажется, что время, необходимое для преобразования массива в кортеж, масштабируется линейно с длиной массива.Есть ли способ сделать это более эффективным?Мне нужно вставить массивы с 5e + 6 элементами в базу данных mysql, но, похоже, MySQLdb принимает только кортежи или списки в качестве ввода для insertmany.

1 Ответ

4 голосов
/ 11 октября 2011

MySQLdb использует re и строковую интерполяцию для объединения параметризованного SQL с аргументами перед передачей запроса на сервер в виде строки. Очевидно, что это не тот путь - вы не только конвертируете массив в кортежи, но и кортежи в строки.

В отличие от этого oursql отправляет запросы SQL на сервер MySQL отдельно от данных.


Поскольку у вас есть 5 массивов, для использования zip (или column_stack) потребуется Python (или numpy), чтобы выделить больше памяти для объединенного объекта (список кортежей или двумерный массив numpy). Чтобы избежать этого, используйте itertools.izip :

import itertools as it
x=np.random.random(1e6)
y=np.random.random(1e6)
connection = oursql.connect(
    host=config.HOST, user=config.USER, passwd=config.PASS, db='test')
with connection.cursor() as cursor:
    sql='INSERT INTO foo (x,y) VALUES (?,?)'
    cursor.executemany(sql,it.izip(x,y))
    print(cursor.lastrowid)

PS. Ранее я предлагал использовать oursql.BinaryIterWrapper. Я не смог чтобы заставить это решение работать, возможно, из-за этой ошибки .

PPS. Я попытался синхронизировать приведенный выше код нашего SQL против аналогичного кода, используя MySQLdb. Тем не менее, для MySQLdb синхронизация невозможна, так как она подняла

_mysql_exceptions.OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")

на cursor.ecutemany(...).

...