簡體   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