Parquet文件推送数据到OSS

1. 任务背景

  • 任务说明:公司 saas 数据分析类产品,客户需要把行为数据回传到客户指定文件系统中(oss)
  • 周期:T+1
  • 数据格式:parquet
  • 数据范围:部分表全量,部分表增量
  • 其他要求:

需要历史数据,部分应用部分周期需要全量一个文件,部分历史需要每天一个文件,新的数据 T+1 。

每个文件上传成功后需要一个状态空文件 _SUCCESS 文件

2. 任务分析

a. 分析

  • 本数据平台 impala+kudu+hive 架构,impala-shll可导出 csv文件。

注:如果系统简单,要求简单,也可以选择数据存成hive表形式,直接文件可parquet文件。这里选择用 impala- shell 导出方式是客户有复杂的要求等等。

  • csv 转 parquet ,并且 parquet文件需要携带 schema 信息。
  • 脚本需要支持按某一时间段的每天处理。

b. 方案

(1)python 做脚本

(2)impala-shell 命令方式导出符合要求的csv文件

(3)pandas 和 pyarraow.parquet 结合操作csv

(4)发送标准文件到 OSS

欢迎关注,一起学习

3. 开发

(1)导出csv文件

impala-shell 
-i {imp_host} 
-d {imp_database}  
-q " {sql} " 
-B --output_delimiter="\\t" 
--print_header 
-o /data/xx.csv

(2) 环境执行

os.system(cmd)

(3) csv 转 parquet

import pyarrow as pa
import pyarrow.parquet as pq

csv_file = pd.read_csv(csvFile, delimiter='\t',low_memory=False)

user_schema = pa.schema([
    ('user_id', pa.int64()),
    ('name', pa.string())
])

table = pa.Table.from_pandas(csv_file,schema=user_schema)

pq.write_table(table, "/data/xxxx.parquet")

(4) 发送到OSS

import oss2

auth_endpoint = 'auth_endpoint'

access_key_id = 'access_key_id'

access_key_secret = 'auth_endpoint'

bucket_name = 'bucket_name'

auth = oss2.Auth(access_key_id, access_key_secret)

bucket = oss2.Bucket(auth,auth_endpoint, bucket_name)


with open(output_file, 'rb') as file_obj:
    # 上传具体数据
    put_object = bucket.put_object(oss_path, file_obj)
    if put_object and put_object.status == 200:
        # 上传_success文件夹
        put_success=bucket.put_object('{0}/_SUCCESS'.format(oss_success_path), '')
        if put_success and put_success.status == 200:
            print("oss data success file upload success")
        else:
            print("oss success data upload fail")
    else:
        print("oss success data upload fail")

(5)日期循环

import datetime

startTime = (datetime.datetime.now() + datetime.timedelta(days=-1)).strftime("%Y%m%d")
endTime = (datetime.datetime.now()).strftime("%Y%m%d")

if (is_today == 0):
    startTime = datetime.datetime.strptime('2025-05-09 00:00:00', '%Y-%m-%d %H:%M:%S').strftime('%Y%m%d')
    endTime = datetime.datetime.strptime('2025-08-17 00:00:00', '%Y-%m-%d %H:%M:%S').strftime('%Y%m%d')

while startTime < endTime:
    
    print('逻辑处理')
    
	startTime = (datetime.datetime.strptime(startTime, '%Y%m%d') + datetime.timedelta(days=1)).strftime(
    '%Y%m%d')

4. 遇到的问题

(1) out of memory

Error tokenizing data. C error: out of memory

因为读取 CSV文件过大,内存放不下,设置 low_memory=False,机器内存小于文件大小,那是倒不出来的,除非分块读取

file_index = 0

for file in pd.read_csv(csvFile, 
                        delimiter='\t',
                        low_memory=False,
                        chunksize=20000):
    
    table = pa.Table.from_pandas(file, schema=schema)
    
	pq.write_table(table, '/data/xxxx_{1}.parquet'.format(file_index))

	file_index+=1

(2) 数据类型转换问题

pyarrow.lib.ArrowTypeError: 
('Expected a string or bytes dtype, got int64', 
 'Conversion failed for column xxxx with type int64')

当数据列出现 Null 的时候,转换 int64 转化不过去,就会报错,需要转为 str 同理一样,其他数据类型也会出现这种情况,当schema定义某列为int64,32,16 .... 的时候,如果出现Null,会自定识别为 float 类型。

csv_file = pd.read_csv(csvFile, delimiter='\t',low_memory=False)

csv_file['xxxx'] = csv_file['xxxx'].astype(str)
### 如何使用 Python Pandas 读取 Parquet 文件 为了读取 Parquet 文件中的数据,可以利用 `pandas` 库提供的功能。首先需要安装必要的库: ```bash pip3 install pandas pyarrow ``` 接着可以通过以下方式加载并查看 Parquet 文件的内容[^1]。 #### 导入所需模块 ```python import pandas as pd from pandas import read_parquet ``` #### 加载 Parquet 文件 通过调用 `read_parquet()` 函数来指定目标文件路径从而完成文件的读取操作: ```python data = read_parquet("myFile.parquet.gzip") print(data.count()) data.head() ``` 上述代码片段展示了如何打开名为 `"myFile.parquet.gzip"` 的压缩文件,并打印其列的数量以及前几行记录。 对于更通用的情况,也可以采用如下方法直接读取未压缩的 `.parquet` 文件并展示部分数据[^2]: ```python df = pd.read_parquet('example.parquet') print(df.head()) ``` 此段脚本同样实现了相同的功能——即获取存储于 `'example.parquet'` 中的信息,并输出表头附近的若干条目给用户查阅。 另外一种更为详细的处理流程涉及到了 `pyarrow` 工具包的应用场景,在某些特定条件下可能更加适用[^3]: ```python import pyarrow.parquet as pq import pandas as pd parquet_file = pq.ParquetFile('./train_parquet/part-00014-918feee1-1ad5-4b08-8876-4364cc996930-c000.snappy.parquet') data = parquet_file.read().to_pandas() df = pd.DataFrame(data) # 可选:将 DataFrame 转换为 CSV 格式保存至本地磁盘 csv_path = './data2.csv' df.to_csv(csv_path) print(f'数据已保存到 {csv_path}') ``` 这段程序不仅完成了对复杂命名模式下的 Snappy 压缩格式的支持,还提供了额外的数据转换选项以便后续分析工作之需。 最后,当关注具体某一列(比如 `context_metadata`)时,则可以根据实际情况调整查询逻辑以适应不同的需求[^4]: ```python if 'context_metadata' in df.columns: for index, row in df.iterrows(): print(f"Row {index + 1}: {row['context_metadata']}") else: print("该 Parquet 文件中不存在 context_metadata 列。") ``` 以上就是关于怎样借助 Python 和 Pandas 来解析 Parquet 文件内所含资料的一些基本介绍和技术要点说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值