Python написать вывод в другой файл fifo pipe?

Я пытаюсь разделить очень большой текстовый файл на две части и выгрузить две части в две разные таблицы MySQL. Я делаю это в Python, проверяю текст построчно и классифицирую каждую строку по коду категории.

Теперь, после того как я разделю текст, как мне передать их в два отдельных файла fifo, чтобы я мог передать эти fifo в клиентские инструменты mysql?

2 ответа

Решение

Я думаю, что вы хотите создать каналы для двух отдельных и, по-видимому, одновременных импортов MySQL из одного и того же скрипта Python?

Хотя это не невозможно сделать с помощью перенаправления оболочки, это будет болезненно. Ваш сценарий Python должен каким-то образом передавать дескрипторы файлов своих каналов в оболочку, чтобы ваш сценарий оболочки мог перенаправить эти файловые дескрипторы командам MySQL.

Гораздо более простым решением является сделать это на Python, с subprocess модуль.

Я не знаю инструмент и синтаксис, который вы надеетесь использовать для выполнения массовой загрузки; все, что вы нам сказали, это то, что вы хотите дать ему "трубу". Итак, я просто предположу, что это mysqlimport команда, упомянутая в ответе hbristow, и что она обрабатывает стандартный ввод через обычное соглашение Unix о предоставлении - как имя файла; поскольку это просто для демонстрации интересной части, в любом случае это не имеет большого значения.

Так:

from subprocess import Popen, stdin

args = ['mysqlimport', my_db_name, '-']
with Popen(args, stdin=PIPE) as import1, Popen(args, stdin=PIPE) as import2:
    with open('giantfile.txt') as f:
        for line in f:
            data = parse(line)
            if belongs_in_import2(data):
                import2.stdin.write(make_sql(data))
            else:
                import1.stdin.write(make_sql(data))

Мы создали два отдельных дочерних процесса, каждый со своим отдельным stdin трубу, и мы можем записать в них так же, как мы можем в любые другие файлы.

Вам может понадобиться import1.stdin.close() а также import2.stdin.close() если mysqlimport Утилита ожидает, что вы закроете /EOF входной файл, прежде чем ожидать его завершения.

Если вы используете Python 2.4-2.7, вы должны установить и использовать subprocess32 портировать. Если по какой-то причине вы не можете этого сделать (или если вы используете Python 3.0-3.1 и по какой-то причине не можете обновить), вы не можете использовать with заявление здесь; вместо этого вам нужно явно close трубы и wait процессы.

Я предполагаю, что вы хотите сделать, это вызвать команду MYSQL

LOAD DATA INFILE

без фактического создания INFILE. Вы можете попробовать использовать mysqlimport клиент командной строки, и при условии, что он счастлив принять канал, сделайте что-то вроде:

python categorize.py --code x big_text_file.txt | mysqlimport db_name /dev/stdin

где ваш скрипт Python разделяет текстовый файл по коду, введенному в командной строке, и выводит результат в виде строки, которая передается в mysqlimport.

Другие вопросы по тегам