簡體   English   中英

逐行處理內存中的文件並在python中生成類似對象的文件

[英]Processing file in memory line by line and producing file like object in python

我需要將大型CSV文件導入postgresql。 該文件使用兩個定界符“,”(逗號)和“ _”(下划線)。

postgres copy命令無法使用兩個定界符,因此在將文件加載到數據庫之前,我先在bash中對其進行處理:

cat large_file.csv \ 
| sed -e 's/_/,/' \ 
| psql -d db -c "COPY large_table FROM STDIN DELIMITER ',' CSV header"

```

我試圖在python中重現此命令,但很難找到sed的python等效項。

使用psycopg,我可以使用python從STDIN復制:

with unzip('large_zip.zip', 'large_file.csv') as file:
    cr.copy_expert('''
        COPY large_table
        FROM STDIN
        DELIMITER ',' CSV HEADER
   ''', file)

該文件很大,可以直接從zip文件加載。 我試圖避免保存本地副本。

逐行處理文件並創建文件(例如可以作為標准輸入發送到python中另一個命令的對象)的最佳方法是什么?

我最近做了這個,我可以告訴你,有一些丑陋的部分,但是絕對有可能。 我不能將代碼原封不動地粘貼在這里,因為它是公司內部的。

基本思想是這樣的:

  1. 通過生成如下代碼來啟動使用來自stdin的數據的程序:

    command = subprocess.Popen(command_list, stdin=subprocess.PIPE)

  2. 對於每個管道(例如command.stdin ),啟動一個threading.Thread進行寫入或讀取。 如果您有多個管道,則需要多個線程。
  3. 在主線程中使用command.wait()等待程序退出。
  4. 停止(加入)所有線程,以便程序不會阻塞。 必須通過從target函數return來確保線程自行退出。

簡單示例(未經測試!):

import shutil
import subprocess
import sys
import threading


lots_of_data = StringIO.StringIO()

import_to_db = subprocess.Popen(["import_to_db"], stdin=subprocess.PIPE)

# Make sure your input stream is at pos 0
lots_of_data.seek(0)

writer = threading.Thread(target=shutil.copyfileobj,
                          args=(lots_of_data, import_to_db.stdin))

writer.start()

return_code = import_to_db.wait()
if return_code:
    print "Error"
    sys.exit(1)

writer.join()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM