python - 逐行处理内存中的文件并像python中的对象一样生成文件

标签 python postgresql file sed copy

我需要将一个大的 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()

关于python - 逐行处理内存中的文件并像python中的对象一样生成文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42898837/

相关文章:

python - 如何将任何数字四舍五入到最接近的 5 的倍数?

sql - 如何使用 SQL 将文本附加到数据库中的重复条目

file - 在 Nim 中捆绑静态资源的最佳方法是什么?

sql - 如果条目不存在,则使用 PostgreSQL 进行多次插入

c# - File.WriteAllLines 不要写 æ, ø 字母

java - 有没有办法在java Scanner中使用变量而不是路径

python - 检测视频文件中的人脸

python - 在使用 xlwriter 将数据帧转换为 excel 文件之前,如何从数据帧中删除索引

python - 为什么这段代码不能作为函数运行?

python - 动态查询