繁体   English   中英

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

[英]Google BigQuery query in Python works when using result(), but Permission issue when using to_dataframe()

升级我的 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()

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

但! 如果您将代码切换为

data = client.query('select * from dataset.table').result()

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

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

我在任何地方都找不到关于这个错误/主题的任何建议,所以如果你们中的任何人遇到同样的事情,我只想分享一下。

解析度

除了 google-cloud-bigquery 包,我还安装了包google-cloud-bigquery-storage 一旦我卸载了那个使用

pip uninstall google-cloud-bigquery-storage

一切又开始工作了! 不幸的是,错误消息并不是那么简单,所以花了一些时间才弄清楚:)

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

BigQuery 存储读取 API 提供了第三个选项,它代表了对先前选项的改进。 当您使用存储读取 API 时,结构化数据以二进制序列化格式通过网络发送。 这允许在多个消费者之间为一组结果提供额外的并行性

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

但是,使用 BQ 存储 API 需要您分别拥有 bigquery.readSessionUser 角色和 readsessions.create 权限,在您的情况下这似乎是缺乏的。

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

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

刚设置
create_bqstorage_client=False

from google.cloud import bigquery
import os
client = bigquery.Client()
query_job = client.query(query)
df = query_job.result().to_dataframe(create_bqstorage_client=False)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM