我需要将大型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文件加载。我试图避免保存本地副本。
逐行处理文件并创建像object这样的文件的最佳方法是什么?我可以作为标准输入发送到python中的另一个命令?
答案 0 :(得分:0)
我最近这样做了,我可以告诉你有一些丑陋的部分,但绝对可能。我不能逐字地粘贴代码,因为它是公司内部的。
基本理念是:
启动程序,该程序使用stdin
生成数据,方法是这样生成:
command = subprocess.Popen(command_list, stdin=subprocess.PIPE)
。
command.stdin
)启动一个threading.Thread
,它写入或读取它。如果您有多个管道,则需要多个线程。command.wait()
退出程序。return
函数target
自行退出。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()