【问题标题】:psycopg2 copy_expert() - how to copy in a gzipped csv file?psycopg2 copy_expert() - 如何复制压缩的 csv 文件?
【发布时间】:2016-12-29 23:19:02
【问题描述】:

如果我的表是 schema_one.table_five 并且我的文件名是 file_to_import.csv.gz,我应该为 copy_expert() cmd 提供什么参数以便将文件内容复制到表中?

这是我正在尝试的:

this_copy = '''COPY schema_one.table_five FROM STDIN with CSV'''
this_file = "file_to_import.csv.gz"
con = psycopg2.connect(dbname=dbname, host=host, port=port, user=user, password=password)
cur = con.cursor()

cur.copy_expert(this_copy, this_file)

这会产生错误:

cur.copy_expert(this_copy, this_file) 
TypeError: file must be a readable file-like object for COPY FROM; a writable file-like object for COPY TO.

那么我如何告诉命令先解压缩文件,然后指定一个分隔符(在本例中为'|')以便处理它。

第二个问题。如果我的文件位于名为“files_to_import”的目录中,即/home/dir1/dir2/files_to_import/file_to_import.csv.gz,有没有一种方法可以只指定目录并在该目录中的所有文件中复制 pgm (到同一张桌子)?它们都是 .csv.gz 文件。


已添加 12-30-16 0940 MST -- 回复评论: 试图让 COPY 语句正确,但所有这些错误 ---

this_file = "staging.tbl_testcopy.csv.gz"
this_copy_01 = '''COPY staging.tbl_testcopy_tmp FROM STDIN'''
this_copy_02 = '''COPY staging.tbl_testcopy_tmp FROM %s'''
this_copy_03 = '''COPY staging.tbl_testcopy_tmp FROM (%s)'''
this_copy_04 = '''COPY staging.tbl_testcopy_tmp FROM f'''

with gzip.open(this_file, 'rb') as f:
    try:
        cur.copy_expert(this_copy_01, f)
    except Exception, e:
        print e
    try:
        cur.copy_expert(this_copy_02, f)
    except Exception, e:
        print e
    try:
        cur.copy_expert(this_copy_03, f)
    except Exception, e:
        print e
    try:
        cur.copy_expert(this_copy_04, f)
    except Exception, e:
        print e

所有这些错误,在同一个地方。那么在“FROM”之后应该是什么?

syntax error at or near "STDIN"
LINE 1: COPY staging.tbl_testcopy_tmp FROM STDIN
                                           ^

syntax error at or near "%"
LINE 1: COPY staging.tbl_testcopy_tmp FROM %s
                                           ^

syntax error at or near "("
LINE 1: COPY staging.tbl_testcopy_tmp FROM (%s)
                                           ^

syntax error at or near "f"
LINE 1: COPY staging.tbl_testcopy_tmp FROM f
                                           ^

【问题讨论】:

    标签: python csv gzip psycopg2


    【解决方案1】:

    copy_expertfile 参数应该是类似文件的对象,而不是文件名。对于常规 csv 文件,您可以使用:

    with open("file_to_import.csv",  'rb') as this_file:
        cur.copy_expert(this_copy, this_file)
    

    对于 gzip 压缩文件,您可以使用 gzip 模块打开文件:

    import gzip
    with gzip.open("file_to_import.csv.gz",  'rb') as this_file:
        cur.copy_expert(this_copy, this_file)
    

    要更改分隔符,您必须更改 COPY 语句。有关更多信息,请参阅 COPY 文档。使用copy_from(有一个可选的sep 参数)而不是copy_expert 可能更容易。

    with gzip.open("file_to_import.csv.gz",  'rb') as this_file:
        cur.copy_from(this_file, 'staging.tbl_testcopy_tmp', sep='|')
    

    没有自动导入目录中所有文件的命令,您必须获取目录内容的列表并循环遍历它。

    【讨论】:

    • 试过但出错:File "./trytest_copy.py", line 24, in <module> cur.copy_expert(this_copy, sys.stdin) psycopg2.ProgrammingError: syntax error at or near "STDIN" LINE 1: COPY schema_one.table_five from STDIN WITH CSV HEADER
    • 您使用过sys.stdin - 这不是我的回答。您需要传递文件句柄。
    • 将其更改为“f”,即文件句柄,但仍然出错。有关代码和结果,请参阅上面编辑的 OP。看起来 FROM 之后发生的任何事情都会导致错误(或者至少我尝试过的所有事情)。对正确构建 COPY 语句有什么建议吗?我要做的就是从我的文件中复制到我的表中。另外,我应该使用 copy_from() 而不是 copy_expert() 吗?我在 w copy_from() 上玩了一会儿,但一无所获。
    • 顺便说一句,目标表是 AWS RedShift 表
    • 是的,正如我在回答中所说,可以使用copy_from 而不是copy_expert。我在声明 COPY staging.tbl_testcopy_tmp FROM STDIN 中找不到问题。也许copy_fromcopy_expert 不适用于redshift。
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多