Python 使用ApacheBeam读取包装在TextIOWrapper中的gzip文件会导致';压缩文件';对象没有属性';可写'&引用;

Python 使用ApacheBeam读取包装在TextIOWrapper中的gzip文件会导致';压缩文件';对象没有属性';可写'&引用;,python,google-cloud-dataflow,apache-beam,Python,Google Cloud Dataflow,Apache Beam,我正在apache beam中实现一个简单的CSV读取器,下面是beam repo的测试: def get_csv_读取器(可读文件): 导入系统 导入csv 输入io 如果sys.version_info>=(3,0): 返回csv.reader(io.TextIOWrapper(可读的\u文件.open())) 其他: 返回csv.reader(可读的文件.open()) 将beam.Pipeline()作为p: 内容物含量(p) |创建([CSV_文件]) |fileio.ReadMatc

我正在apache beam中实现一个简单的CSV读取器,下面是beam repo的测试:

def get_csv_读取器(可读文件):
导入系统
导入csv
输入io
如果sys.version_info>=(3,0):
返回csv.reader(io.TextIOWrapper(可读的\u文件.open()))
其他:
返回csv.reader(可读的文件.open())
将beam.Pipeline()作为p:
内容物含量(p)
|创建([CSV_文件])
|fileio.ReadMatches()
|beam.FlatMap(获取csv阅读器)
|电子地图(印刷版))
如果CSV_文件未压缩且我没有收到任何错误,则此功能正常工作。但是,如果我使用gzip文件作为输入,我会得到:

获取csv读取器(可读文件)中的

6导入io
7如果sys.version_info>=(3,0):
---->8返回csv.reader(io.TextIOWrapper(可读的\u文件.open()))
9其他:
10返回csv.reader(可读的文件.open())
AttributeError:“CompressedFile”对象没有“writable”属性[在运行“FlatMap(get\u csv\u reader)”时]

我理解为什么会发生这种情况(TextIOWrapper正在寻找可读写的对象)。是否有人对ApacheBeam/dataflow有更深入的了解,可以建议如何最好地实现它来处理压缩和未压缩的输入

从2.18.0版本的Beam开始,您将能够执行以下操作:

def get_csv_reader(readable_file):
  import sys
  import csv
  import io
  if sys.version_info >= (3, 0):
    return csv.reader(io.TextIOWrapper(readable_file.open(compression_type=MY_COMPRESSION)))
  else:
    return csv.reader(readable_file.open(compression_type=MY_COMPRESSION))

with beam.Pipeline() as p:
  content_pc = (p
                | beam.Create([CSV_FILE])
                | fileio.ReadMatches()
                | beam.FlatMap(get_csv_reader)
                | beam.Map(print))

从Beam中的2.18.0版本开始,您将能够执行以下操作:

def get_csv_reader(readable_file):
  import sys
  import csv
  import io
  if sys.version_info >= (3, 0):
    return csv.reader(io.TextIOWrapper(readable_file.open(compression_type=MY_COMPRESSION)))
  else:
    return csv.reader(readable_file.open(compression_type=MY_COMPRESSION))

with beam.Pipeline() as p:
  content_pc = (p
                | beam.Create([CSV_FILE])
                | fileio.ReadMatches()
                | beam.FlatMap(get_csv_reader)
                | beam.Map(print))

Pablo()给出的答案即使在我将Beam版本更新为2.18.0或2.19.0之后也不起作用

复制失败。
GZ_FILE_PATTERN='/local/path/to/some wildcard-*.GZ'
def get_csv_读取器(可读_文件):
返回csv.reader(io.TextIOWrapper(readable_file.open(compression_type=CompressionTypes.GZIP)))
将beam.Pipeline()作为p:
进程=\
(p
|匹配文件(GZ_文件_模式)
|ReadMatches()
|beam.FlatMap(获取csv阅读器)
|波束图(打印)
)
错误消息:

AttributeError:“CompressedFile”对象没有“writable”属性[在运行“FlatMap(get\u csv\u reader)”时]

(从v2.19.0开始,尚未合并修补程序,也未修复此问题?)

目前,我决定避免使用
CompressionTypes.GZIP
并自行解压缩文件

复制以正确工作。
GZ_FILE_PATTERN='/local/path/to/some wildcard-*.GZ'
def get_csv_读取器(可读的_文件_元数据):
#Hack:将未压缩传递到BEAM
使用FileSystems.open(可读的\u file\u metadata.path,压缩类型=压缩类型.UNCOMPRESSED)作为fopen:
#自己减压
decompressed_str=io.StringIO(gzip.decompress(fopen.read()).decode('utf-8'))
返回csv.reader(已解压缩)
将beam.Pipeline()作为p:
进程=\
(p
|匹配文件(GZ_文件_模式)
|beam.FlatMap(获取csv阅读器)
|波束图(打印)
)

即使在我将Beam版本更新为2.18.0或2.19.0之后,Pablo()发布的答案仍然不起作用

复制失败。
GZ_FILE_PATTERN='/local/path/to/some wildcard-*.GZ'
def get_csv_读取器(可读_文件):
返回csv.reader(io.TextIOWrapper(readable_file.open(compression_type=CompressionTypes.GZIP)))
将beam.Pipeline()作为p:
进程=\
(p
|匹配文件(GZ_文件_模式)
|ReadMatches()
|beam.FlatMap(获取csv阅读器)
|波束图(打印)
)
错误消息:

AttributeError:“CompressedFile”对象没有“writable”属性[在运行“FlatMap(get\u csv\u reader)”时]

(从v2.19.0开始,尚未合并修补程序,也未修复此问题?)

目前,我决定避免使用
CompressionTypes.GZIP
并自行解压缩文件

复制以正确工作。
GZ_FILE_PATTERN='/local/path/to/some wildcard-*.GZ'
def get_csv_读取器(可读的_文件_元数据):
#Hack:将未压缩传递到BEAM
使用FileSystems.open(可读的\u file\u metadata.path,压缩类型=压缩类型.UNCOMPRESSED)作为fopen:
#自己减压
decompressed_str=io.StringIO(gzip.decompress(fopen.read()).decode('utf-8'))
返回csv.reader(已解压缩)
将beam.Pipeline()作为p:
进程=\
(p
|匹配文件(GZ_文件_模式)
|beam.FlatMap(获取csv阅读器)
|波束图(打印)
)

我试过你的代码片段,是的。有趣的问题。虽然我觉得根本原因和beam无关?把它放在正确的标签下将有助于更快地找到正确的答案。我懂了。你是对的。我是python API新手,没有意识到ReadableFile来自beam。这并不理想,但
ReadableFile
将文件路径作为一个名为
metadata.path
的属性包含。您可以使用它打开文件:
filesystems.filesystems.open(rf.metadata.path,compression=MY\u compression)
。您可能仍然需要使用TextIOWrapper。如果有帮助的话,请不要担心。我刚刚写了一个补丁:-它应该在Beam 2.18.0中可用。添加了提示作为答案。我尝试了你的代码片段,是的。有趣的问题。虽然我觉得根本原因和beam无关?把它放在正确的标签下将有助于更快地找到正确的答案。我懂了。你是对的。我是python API新手,没有意识到ReadableFile来自beam。这并不理想,但
ReadableFile
将文件路径作为一个名为
metadata.path
的属性包含。您可以使用它打开文件:
filesystems.filesystems.open(rf.metadata.path,compression=MY\u compression)
。您可能仍然需要使用TextIOWrapper。如果有帮助的话,请不要担心。我刚刚写了一个补丁:-它应该在Beam 2.18.0中可用。添加了提示作为答案。这对于