Помощь с загрузкой данных MySQL INFILE - PullRequest
3 голосов
/ 06 августа 2009

Я хочу загрузить CSV-файл, который выглядит следующим образом:

Acct. No.,1-15 Days,16-30 Days,31-60 Days,61-90 Days,91-120 Days,Beyond 120 Days
2314134101,898.89,8372.16,5584.23,7744.41,9846.54,2896.25
2414134128,5457.61,7488.26,9594.02,6234.78,273.7,2356.13
2513918869,2059.59,7578.59,9395.51,7159.15,5827.48,3041.62
1687950783,4846.85,8364.22,9892.55,7213.45,8815.33,7603.4
2764856043,5250.11,9946.49,8042.03,6058.64,9194.78,8296.2
2865446086,596.22,7670.04,8564.08,3263.85,9662.46,7027.22
,4725.99,1336.24,9356.03,1572.81,4942.11,6088.94
,8248.47,956.81,8713.06,2589.14,5316.68,1543.67
,538.22,1473.91,3292.09,6843.89,2687.07,9808.05
,9885.85,2730.72,6876,8024.47,1196.87,1655.29

Но если вы заметили, некоторые поля не заполнены. Я думаю, что MySQL просто пропустит строку, в которой отсутствует первый столбец. Когда я запускаю команду:

LOAD DATA LOCAL INFILE 'test-long.csv' REPLACE INTO TABLE accounts
    FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n'
    IGNORE 1 LINES
    (cf_535, cf_580, cf_568, cf_569, cf_571, cf_572);

И вывод MySQL:

Query OK, 41898 rows affected, 20948 warnings (0.78 sec)
Records: 20949  Deleted: 20949  Skipped: 0  Warnings: 20948

Количество строк составляет всего 20 949, но MySQL сообщает об этом как о 41 898 поврежденных строках. Почему так? Кроме того, ничего не изменилось в таблице. Я также не мог видеть, о чем генерируются предупреждения. Я хотел использовать LOAD DATA INFILE, потому что требуется python полсекунды для обновления каждой строки, что составляет 2,77 часа для файла с более чем 20 000 записей.

ОБНОВЛЕНИЕ: Изменен код для установки автоматической фиксации на 'False' и добавлен оператор db.commit ():

# Tell MySQLdb to turn off auto-commit
db.autocommit(False) 

# Set count to 1
count = 1
while count < len(contents):
    if contents[count][0] != '':
        cursor.execute("""
            UPDATE accounts SET cf_580 = %s, cf_568 = %s, cf_569 = %s, cf_571 = %s, cf_572 = %s
            WHERE cf_535 = %s""" % (contents[count][1], contents[count][2], contents[count][3], contents[count][4], contents[count][5], contents[count][0]))
    count += 1

try:
    db.commit()
except:
    db.rollback()

Ответы [ 2 ]

2 голосов
/ 06 августа 2009

У вас есть в основном 3 вопроса здесь. В обратном порядке

  1. Вы делаете вставки Python в отдельные операторы? Вы, вероятно, хотите окружить их всех начальной транзакцией / фиксацией. 20 000 коммитов могут легко занять часы.
  2. Ваш оператор импорта определяет 6 полей, но CSV имеет 7 полей. Это объясняет число двойных строк: каждая строка ввода приводит к 2 строкам в базе данных, 2-я строка с полями 2-6 пустыми.
  3. Неполные строки будут вставлены с нулевыми значениями или значениями по умолчанию для отсутствующих столбцов. Это может быть не то, что вы хотите с этими искаженными рядами.

Если ваша программа на Python не может работать достаточно быстро даже с одной транзакцией, вы должны по крайней мере попросить программу Python отредактировать / очистить файл данных перед импортом. Если действует Номер является первичным ключом, что представляется разумным, вставка строк с пробелом приведет либо к сбою всего импорта, либо, если включен автоматический номер, к импорту фиктивных данных.

0 голосов
/ 25 августа 2009

Если вы используете ключевое слово REPLACE в LOAD DATA, то число после «Deleted:» показывает, сколько строк было фактически заменено

...