You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EC2服务器上Python客户端库执行BigQuery查询失败排查

在EC2服务器上使用Python BigQuery客户端执行查询失败,报SSL证书验证错误

问题详情

在EC2服务器上运行以下Python代码调用BigQuery查询时,仅打印run_bigquery_query_thread started,无后续输出,也无错误抛出,BigQuery账户无查询记录。相同代码在Google Colab可正常运行:

def run_bigquery_query_thread(query): 
     print("run_bigquery_query_thread started") 
     # Run the query and get the results 
     query_job = client.query(query) 
     print(query_job) 
     results = query_job.result() 
     return results

添加调试日志后,捕获到SSL证书验证错误:

logging.basicConfig()
logging.getLogger('google.cloud.bigquery').setLevel(logging.DEBUG)

错误信息:

connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)'))': /token

已尝试的操作:

  • 下载Google pem文件
  • 安装certify并替换cacert.pem
  • 设置环境变量GOOGLE_APPLICATION_CREDENTIALS指向证书文件,但问题仍未解决。

问题原因及排查解决步骤

1. 修正认证文件的混淆问题

GOOGLE_APPLICATION_CREDENTIALS指向的应该是Google服务账号的JSON密钥文件,而非SSL根证书的pem文件。你之前可能混淆了两类文件:

  • JSON密钥:用于BigQuery身份认证,从Google Cloud控制台的服务账号页面下载
  • pem证书:用于SSL连接的根证书信任验证

2. 补全EC2系统的根证书信任链

EC2默认系统证书存储可能缺少Google服务所需的根证书,导致SSL握手失败:

  • 将下载的Google根证书pem文件复制到系统证书目录(以Amazon Linux 2为例,路径为/etc/pki/ca-trust/source/anchors/)
  • 运行命令更新证书信任链:
sudo update-ca-trust extract

3. 强制指定证书路径给Python依赖库

Google云客户端底层依赖requests库,可通过环境变量直接指定证书文件路径:

import os
# 替换为你的cacert.pem实际路径
os.environ['REQUESTS_CA_BUNDLE'] = '/home/ec2-user/cacert.pem'
# 替换为你的服务账号JSON密钥路径
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = '/home/ec2-user/your-service-account-key.json'

4. 检查EC2网络连通性

  • 用curl测试能否正常访问BigQuery API端点:
curl -v https://bigquery.googleapis.com

如果存在代理或防火墙拦截,需配置代理环境变量:

os.environ['HTTP_PROXY'] = 'http://your-proxy:port'
os.environ['HTTPS_PROXY'] = 'https://your-proxy:port'

5. 升级Google Cloud客户端版本

旧版本的BigQuery客户端可能存在证书相关bug,更新到最新版本:

pip install --upgrade google-cloud-bigquery google-auth

6. 单独测试认证流程

先跳过查询,测试基础认证是否正常,定位问题层级:

from google.auth import default
from google.auth.transport.requests import Request

credentials, project_id = default()
credentials.refresh(Request())
print("认证成功,令牌有效期:", credentials.expiry)

若这段代码报错,说明身份认证或SSL连接存在问题;若成功,再尝试执行查询。


内容的提问来源于stack exchange,提问作者idan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 17:07:21