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.