Python 中的 Google BigQuery 查询在使用 result() 时有效,但在使用 to_dataframe() 时出现权限问题

Mic*_*ela 5 python google-cloud-storage google-bigquery

升级 pip 包和返回查询结果的 bigquery 连接器突然停止工作并出现以下错误消息后,我遇到了问题

from google.cloud import bigquery
from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file('path/to/file', scopes=['https://www.googleapis.com/auth/cloud-platform',
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/bigquery'
])

client = bigquery.Client(credentials=credentials)
data = client.query('select * from dataset.table').to_dataframe()
Run Code Online (Sandbox Code Playgroud)

PermissionDenied:403请求失败:用户没有bigquery.readsessions.create'权限

但!如果您将代码切换为

data = client.query('select * from dataset.table').result()
Run Code Online (Sandbox Code Playgroud)

(dataframe -> result) 您收到了 RowIterator 格式的数据并能够正确读取它们。

使用具有相同凭据的 to_dataframe 的相同脚本正在服务器上运行。因此我将bigquery包设置为相同的版本2.28.0,但这仍然没有帮助。

我在任何地方都找不到关于此错误/主题的任何建议,所以我只想分享是否有人遇到同样的事情。

Tho*_* W. 4

从 bigquery 接收数据的方式有多种。与其他选项相比,对于较大的结果集,使用BQ Storage API被认为更有效:

BigQuery Storage Read API 提供了第三个选项,该选项比之前的选项有所改进。当您使用存储读取 API 时,结构化数据会以二进制序列化格式通过线路发送。这允许多个消费者之间对一组结果进行额外的并行处理

Python BQ 库内部决定是否可以使用 BQ Storage API。对于结果方法,它在内部使用传统的 tabledata.list 方法,而 to_dataframe 方法使用 BQ Storage API(如果安装了相应的包)。

然而,使用 BQ 存储 API 要求您分别拥有 bigquery.readSessionUser 角色和 readsessions.create 权限,在您的情况下似乎缺少这些权限。

通过卸载 google-cloud-bigquery-storage,google-cloud-bigquery 包将回退到 list 方法。因此,通过卸载此软件包,您可以解决权限不足的问题。

有关详细信息,请参阅BQ Python 库文档