2010-02-18 2 views
1

У меня возникли проблемы с сценарием Python, который в основном только анализируя CSV-файл строку за строкой, а затем вставляя каждую строку в таблицу MySQL, используя для цикла:Python MySQL запрос не завершения

f = csv.reader(open(filePath, "r")) 
i = 1 
for line in f: 
    if (i > skipLines): 
     vals = nullify(line) 
     try: 
      cursor.execute(query, vals) 
     except TypeError: 
      sys.exc_clear() 
    i += 1 
return 

в случае, если запрос имеет вид:

query = ("insert into %s" % tableName) + (" values (%s)" % placeholders) 

Это работает прекрасно с каждым файлом используется для с одним исключением - самого большого файла. Он останавливается в разных точках каждый раз - иногда он достигает 600 000 записей, иногда 900 000. Но всего около 4 000 000 записей.

Я не могу понять, почему он это делает. Тип таблицы - MyISAM. Доступно много свободного места на диске. Когда он останавливается, таблица достигает около 35 МБ. max_allowed_packet установлен в 16 МБ, но я не думаю, что это проблема, поскольку она выполняется по очереди.

У кого-нибудь есть идеи, что это может быть? Не уверен, что за это отвечает Python, MySQL или MySQLdb.

Заранее спасибо.

+0

Есть ли причина, по которой вы не можете использовать встроенную функцию импорта CSV MySQL? http://dev.mysql.com/doc/refman/5.1/en/load-data.html –

+0

Когда вы говорите, что это «останавливается», вы могли бы разработать? Вызывает ли это исключение, становится невосприимчивым и т. Д.? – swanson

+0

Причина, по которой я решил не использовать 'LOAD DATA', заключается в том, что я буду добавлять функции, которые будут изменять каждую запись, прежде чем вставлять их. Возможно, было бы лучше изменить каждую строку в новом CSV-файле, а затем использовать 'LOAD DATA' для импорта нового CSV-файла? – edanfalls

ответ

1

Вы пробовали LOAD Функция MySQL?

query = "LOAD DATA INFILE '/path/to/file' INTO TABLE atable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' ESCAPED BY '\\\\'" 
cursor.execute(query) 

Вы всегда можете предварительно обработать файл CSV (по крайней мере, это то, что я делаю :)

Еще одна вещь, которую стоит бы сыпучие вставки. Вы можете попытаться вставить несколько строк с одним запросом:

INSERT INTO x (a,b) 
VALUES 
('1', 'one'), 
('2', 'two'), 
('3', 'three') 

Ах, да, и вам не нужно совершать, так как это MyISAM двигатель.

+0

Я знал о «LOAD», но решил не использовать его, считая, что лучше обработать и вставить одну строку за раз. Однако теперь, когда вы упомянули об этом, я думаю, что предпочитаю ваше решение; Обработка MySQL будет уменьшена, и это упростит сохранение атомарности. Также упрощает архивирование, поскольку я могу просто поместить измененные CSV-файлы. Спасибо :) – edanfalls

0

Как ссылается С. Лотт, не являются ли курсоры, используемые в качестве ручек в транзакции?

Так что в любое время db дает вам возможность откатывать все эти ожидающие вставки.

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

+0

Да, я попробовал это, чтобы убедиться. Оказалось, что в любом случае у меня была автокомбинация, поэтому каждый запрос MySQL автоматически включался в свою транзакцию. – edanfalls

Смежные вопросы