本文主要介绍如何使用Python SDK的SelectObject查询CSV和JSON文件。

说明 有关SelectObject的更多详情,请参考开发指南SelectObjectSelectObjectAPI。

Python SDK示例

以下代码用于查询CSV和JSON文件:

import oss2

def select_call_back(consumed_bytes, total_bytes =  None):
        print('Consumed Bytes:' + str(consumed_bytes) + '\n')

access_key_id = '<yourAccessKeyId>'
access_key_secret = '<yourAccessKeySecret>'
bucket_name = '<yourtBucketName>'
endpoint = '<yourEndpoint>'

# 创建存储空间,所有文件相关的方法都需要通过存储空间来调用。
bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)
key =  'python_select.csv'
content =  'Tom Hanks,USA,45\r\n'*1024
filename =  'python_select.csv'

# 上传CSV文件。
bucket.put_object(key, content)
# Select API的参数。
csv_meta_params = {'RecordDelimiter': '\r\n'}
select_csv_params = {'CsvHeaderInfo': 'None',
                    'RecordDelimiter': '\r\n',
                    'LineRange': (500, 1000)}

csv_header = bucket.create_select_object_meta(key, csv_meta_params)
print(csv_header.rows)
print(csv_header.splits)
result = bucket.select_object(key, "select * from ossobject where _3 > 44", select_call_back, select_csv_params)
select_content = result.read()
print(select_content)

result = bucket.select_object_to_file(key, filename,
      "select * from ossobject where _3 > 44", select_call_back, select_csv_params)
bucket.delete_object(key)

###JSON DOCUMENT
key =  'python_select.json'
content =  "{\"contacts\":[{\"key1\":1,\"key2\":\"hello world1\"},{\"key1\":2,\"key2\":\"hello world2\"}]}"
filename =  'python_select.json'
# 上传JSON DOCUMENT。
bucket.put_object(key, content)
select_json_params = {'Json_Type': 'DOCUMENT'}
result = bucket.select_object(key, "select s.key2 from ossobject.contacts[*] s where s.key1 = 1", None, select_json_params)
select_content = result.read()
print(select_content)

result = bucket.select_object_to_file(key, filename,
      "select s.key2 from ossobject.contacts[*] s where s.key1 = 1", None, select_json_params)
bucket.delete_object(key)

###JSON LINES
key =  'python_select_lines.json'
content =  "{\"key1\":1,\"key2\":\"hello world1\"}\n{\"key1\":2,\"key2\":\"hello world2\"}"
filename =  'python_select.json'
# 上传JSON LINE。
bucket.put_object(key, content)
select_json_params = {'Json_Type': 'LINES'}
json_header = bucket.create_select_object_meta(key,select_json_params)
print(json_header.rows)
print(json_header.splits)

result = bucket.select_object(key, "select s.key2 from ossobject s where s.key1 = 1", None, select_json_params)
select_content =  result.read()
print(select_content)
result = bucket.select_object_to_file(key, filename,
           "select s.key2 from ossobject s where s.key1 = 1", None, select_json_params)
bucket.delete_object(key)

Python Select API

以下内容是对Python Select API中的select_object、select_object_to_file、create_select_object_meta等元素的详细介绍。

  • select_object
    • select_object 示例:
      def select_object(self, key, sql,
                         progress_callback=None,
                         select_params=None
                         byte_range=None
                         headers=None                
                         ):

      以上示例用于对指定Key的文件运行SQL,并返回查询结果。

      • sql是原始的SQL字符串,无需做base64编码。
      • Progress_callback是可选的用来汇报进度的回调函数。
      • select_params用于指定select执行的各种参数以及行为。
      • headers用于指定请求中附带的header信息,其行为和get-object一致。比如,对于CSV文件,在某些情况下可以用bytes来指定SQL查询在文件中的范围。
    • select_params支持的参数
      参数名称 描述
      Json_Type
      • 当Json_Type没有指定时,默认为CSV文件。
      • 当Json_Type指定为DOCUMENT时,该文件为JSON DOCUMENT文件。
      • 当Json_Type指定为LINES时,该文件为JSON LINE文件。
      CsvHeaderInfo CSV的header信息。

      合法值为NoneIgnore以及Use

      • None:该文件没有header信息。
      • Ignore:该文件有header信息但未在SQL中使用。
      • Use:该文件有Header信息且在sql语句中使用了Header中的列名。
      CommentCharacter CSV中的注释字符。仅支持一个字符,默认为None表示没有注释字符。
      RecordDelimiter CSV中的行分隔符,仅支持一个或两个字符。默认为\n。
      OutputRecordDelimiter Select输出结果中的行分隔符。默认为\n。
      FieldDelimiter CSV的列分隔符,仅支持一个字符,默认为逗号(,)。
      OutputFieldDelimiter Select输出结果中的列分隔符,默认为逗号(,)。
      QuoteCharacter CSV 列的引号字符,只支持一个字符,默认为双引号。引号内的行列分隔符被当做普通字符处理。
      SplitRange 使用Split做分片查询。格式为(start, end),此处为闭区间,表示查询范围从Split start#到end#。
      LineRange 使用行做分片查询。格式为(start, end),此处为闭区间,表示查询范围从行号start#到end#。
      CompressionType 压缩类型,可以为GZIP。默认为None。
      KeepAllColumns 该参数设置为true时表示原CSV文件中未在select列中出现的列将以空值输出(但保留列的位置)。默认为False。
      如果CSV文件中的列为 firstname, lastname, age,SQL为select firstname, age from ossobject
      • 如果KeepAllColumnstrue,则输出为firstname,,age(中间多一个逗号)。
      • 如果KeepAllColumnsfalse,则输出为firstname,age。
      说明 引入该选项的原因是让原本处理GetObject返回数据的代码可以在不用修改的情况下平移切换到SelectObject。
      OutputRawData
      • 该参数为True时表示输出为Select数据,没有Frame的包装,表明很长时间不返回数据时会引起超时。
      • 该参数为False时表示输出为Frame包装的数据。默认是False。
      EnablePayloadCrc 为每个Frame计算CRC校验值,默认为False。
      OutputHeader 仅用于CSV文件,表示输出结果中第一行是Header信息。
      SkipPartialDataRecord 该参数为True时,如果CSV中某一列值不存在或者Json中某一个Key不存在,则直接跳过整个记录。该参数为False时,则把该列当做null来处理。
      假如某一行的列为firstname,lastname,age。SQL为select _1, _4 from ossobject
      • 如果为True,则直接跳过此行。
      • 如果为False,则返回firstname,\n。
      MaxSkippedRecordsAllowed 允许跳过的行的最大值。默认为0,表示一旦有一行跳过就返回错误。
      ParseJsonNumberAsString
      • 当该参数为True时:表示Json文件中的数字都解析为字符串。
      • 当参数为False时:按照整数或者浮点数进行解析,False为默认值。

      当Json文件中含有高精度的浮点数时,直接解析为浮点数会丢失精度。如果想保留原始的精度,则可以设置该参数为True,并且在SQL语句中将该列Cast为decimal类型即可。

    • select_object 返回值:返回SelectObjectResult对象,该对象支持read()函数以获得所有select结果。同时也支持__iter__方法。
      说明 如果Select结果偏大,调用read()函数会阻塞直到select结果完全返回,同时占用过多的内存。 建议使用__iter__方法(foreach chunk in result),然后对每个chunk进行处理。__iter__方法不仅可以降低内存使用,且OSS服务器端每处理一个请求chunk客户端都能及时处理,不必等到全部结果返回后才处理。
  • select_object_to_file
    def select_object_to_file(self, key, filename, sql,
                       progress_callback=None,
                       select_params=None
                       headers=None
                       ):

    以上示例用于对指定Key的文件运行SQL,将查询结果写入指定的文件。

    涉及的参数描述与select_object相同。

  • create_select_object_meta
    • create_select_object_meta的语法结构
      def create_select_object_meta(self, key, select_meta_params=None, header=None):

      以上示例用于对指定Key的文件进行创建或者获取select meta。select meta是指该文件的总行数、总列数(CSV文件)、总的Split数。

      如果该文件已经创建过meta,则调用该函数不会重新创建,除非在参数中指定OverwriteIfExists为true。

      创建select meta需要扫描整个文件。

    • select_meta_params 中支持的参数
      参数名称 描述
      Json_Type
      • 当Json_Type没有指定时,默认为CSV文件。
      • 若指定,必须为LINES,表示文件是Json LINES。
      说明 JSON DOCUMENT不支持该操作。
      RecordDelimiter CSV文件换行符。
      FieldDelimiter CSV文件列分隔符。
      QuoteCharacter CSV文件列引号符。引号符内的行列分隔符按普通字符处理。
      CompressionType 压缩类型。目前不支持任何压缩类型,故只能为None。
      OverwriteIfExists 覆盖原有的Select Meta。正常情况无需使用该选项。
    • create_select_object_meta 返回值: GetSelectObjectMetaResult对象,包括rows、 splits 两个属性。对于CSV文件,其内部的select_resp对象还包括columns值,表示CSV文件的列数。