常见问题
如何查看当前使用的 PyODPS 版本
import odps
print(odps.__version__)
安装失败 / 出现问题
请参考 PyODPS 安装常见问题解决 。
提示 Project not found
Endpoint配置不对,详细配置参考 MaxCompute 开通 Region 和服务连接对照表 。 此外还需要注意 ODPS 入口对象参数位置是否填写正确。
如何手动指定 Tunnel Endpoint
可以使用下面的方法创建带有 Tunnel Endpoint 的 ODPS 入口(参数值请自行替换,不包含星号):
import os
from odps import ODPS
# 保证 ALIBABA_CLOUD_ACCESS_KEY_ID 环境变量设置为用户 Access Key ID,
# ALIBABA_CLOUD_ACCESS_KEY_SECRET 环境变量设置为用户 Access Key Secret,
# 不建议直接使用 Access Key ID / Access Key Secret 字符串
o = ODPS(
os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
project='**your-project**',
endpoint='**your-endpoint**',
tunnel_endpoint='**your-tunnel-endpoint**',
)
怎么配置 SQL / DataFrame 的执行选项?
ODPS SQL 的执行选项可在 这里 找到。设置时,可将该选项设置到 options.sql.settings
,即
from odps import options
# 将 <option_name> 和 <option_value> 替换为选项名和选项值
options.sql.settings = {'<option_name>': '<option_value>'}
也可在每次调用执行时即席配置,该配置中的配置项会覆盖全局配置。
当使用
odps.execute_sql
时,可以使用from odps import options # 将 <option_name> 和 <option_value> 替换为选项名和选项值 o.execute_sql('<sql_statement>', hints={'<option_name>': '<option_value>'})
当使用
dataframe.execute
或dataframe.persist
时,可以使用from odps import options # 将 <option_name> 和 <option_value> 替换为选项名和选项值 df.persist('<table_name>', hints={'<option_name>': '<option_value>'})
读取数据时报”project is protected”
Project 上的安全策略禁止读取表中的数据,此时,如果想使用全部数据,有以下选项可用:
联系 Project Owner 增加例外规则
使用 DataWorks 或其他脱敏工具先对数据进行脱敏,导出到非保护 Project,再进行读取
如果只想查看部分数据,有以下选项
改用
o.execute_sql('select * from <table_name>').open_reader()
改用 DataFrame,
o.get_table('<table_name>').to_df()
出现 ImportError,并且在 ipython 或者 jupyter 下使用
如果 from odps import errors
也不行,则是缺少 ipython 组件,执行 pip install -U jupyter
解决。
执行 SQL 通过 open_reader 只能取到最多1万条记录,如何取多余1万条?
使用 create table as select ...
把SQL的结果保存成表,再使用 table.open_reader 来读取。
上传 pandas DataFrame 到 ODPS 时报错:ODPSError: ODPS entrance should be provided
原因是没有找到全局的ODPS入口,有三个方法:
使用 room 机制 ,
%enter
的时候,会配置全局入口对odps入口调用
to_global
方法使用odps参数,
DataFrame(pd_df).persist('your_table', odps=odps)
在 DataFrame 中如何使用 max_pt ?
使用 odps.df.func
模块来调用 ODPS 内建函数
from odps.df import func
df = o.get_table('your_table').to_df()
df[df.ds == func.max_pt('your_project.your_table')] # ds 是分区字段
通过 DataFrame 写表时报 table lifecycle is not specified in mandatory mode
Project 要求对每张表设置 lifecycle,因而需要在每次执行时设置
from odps import options
options.lifecycle = 7 # 或者你期望的 lifecycle 整数值,单位为天
执行 SQL 时报 Please add put { “odps.sql.submit.mode” : “script”} for multi-statement query in settings
请参考 SQL设置运行参数 。
如何遍历 PyODPS DataFrame 中的每行数据
PyODPS DataFrame 不支持遍历每行数据。这样设计的原因是由于 PyODPS DataFrame 面向大规模数据设计,在这种场景下,
数据遍历是非常低效的做法。我们建议使用 DataFrame 提供的 apply
或 map_reduce
接口将原本串行的遍历操作并行化,
具体可参见 这篇文章 。如果确认你的场景必须要使用数据遍历,
而且遍历的代价可以接受,可以使用 to_pandas
方法将 DataFrame 转换为 Pandas DataFrame,或者将 DataFrame
存储为表后使用 read_table
或者 Tunnel 读取数据。
为何调用 to_pandas 后内存使用显著大于表的大小?
有两个原因可能导致这个现象发生。首先,MaxCompute 在存储数据时会对数据进行压缩,你看到的表大小应当是压缩后的大小。
其次,Python 中的值存在额外的存储开销。例如,对于字符串类型而言,每个 Python 字符串都会额外占用近 40 字节空间,
即便该字符串为空串,这可以通过调用 sys.getsizeof("")
发现。
需要注意的是,使用 Pandas 的 info
或者 memory_usage
方法获得的 Pandas DataFrame
内存使用可能是不准确的,因为这些方法默认不计算 string 或者其他 object 类型对象的实际内存占用。使用
df.memory_usage(deep=True).sum()
获得的大小更接近实际内存使用,具体可参考
这篇 Pandas 文档 。
为减小读取数据时的内存开销,可以考虑使用 Arrow 格式,具体可以参考 这里。