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

云函数调用Oracle数据库报DPI-1047错误,如何关联云存储桶中的Oracle Client库?

问题描述

构建调用Oracle数据库的云函数时遇到以下问题:

  • 已编写Python查询代码并存入代码库,HTTP触发器运行正常
  • Oracle Client Library已上传至同区域云存储桶,但云函数运行时抛出找不到Oracle客户端库的错误
  • 错误信息:

Error: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory"

相关代码如下:

import cx_Oracle
def queryOracleDatabase(request):
    # Oracle Database Connection
    username = 'x'
    password = 'y'
    connStr = '00.00.00.00:0000/abcd'
    try:
        conn = cx_Oracle.connect(username, password, connStr)
    except cx_Oracle.DatabaseError as e:
        error = e.args
        print('Error: ', error.message)
        return

    # Execute the query
    try:
        cursor = conn.cursor()
        cursor.execute('select * table')  # 注意:此处SQL语法错误,应为select * from table
        data = cursor.fetchall()
    except cx_Oracle.DatabaseError as e:
        error = e.args
        print('Error: ', error.message)
        return
    
    # Clean up
    cursor.close()
    conn.close()
    
    return data
解决步骤

1. 配置云函数的存储桶访问权限

为云函数关联的服务账号添加存储对象查看器(或等价的读取权限),确保云函数有权限读取存储桶中的Oracle Client Library文件。

2. 在云函数启动时下载客户端库到临时目录

云函数运行环境仅/tmp目录可写,需在代码执行前将存储桶中的Oracle Client Library(建议打包为zip压缩包)下载到该目录并解压。以GCP云函数为例,示例代码片段如下:

from google.cloud import storage
import os
import zipfile

def download_oracle_client():
    bucket_name = "你的存储桶名称"
    source_blob_name = "oracle_client.zip"  # 存储桶中客户端库压缩包的路径
    destination_file_name = "/tmp/oracle_client.zip"
    extract_path = "/tmp/oracle_client"

    # 初始化存储客户端
    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(source_blob_name)

    # 下载压缩包到临时目录
    blob.download_to_filename(destination_file_name)

    # 解压压缩包
    with zipfile.ZipFile(destination_file_name, 'r') as zip_ref:
        zip_ref.extractall(extract_path)
    
    # 设置环境变量,让cx_Oracle能找到客户端库文件
    os.environ['LD_LIBRARY_PATH'] = f"{extract_path}/lib:{os.environ.get('LD_LIBRARY_PATH', '')}"

3. 修改原函数,整合客户端初始化逻辑

在queryOracleDatabase函数开头调用上述初始化函数,确保连接Oracle前已完成客户端库的配置:

import cx_Oracle
from google.cloud import storage
import os
import zipfile

def download_oracle_client():
    bucket_name = "你的存储桶名称"
    source_blob_name = "oracle_client.zip"
    destination_file_name = "/tmp/oracle_client.zip"
    extract_path = "/tmp/oracle_client"

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(source_blob_name)
    blob.download_to_filename(destination_file_name)

    with zipfile.ZipFile(destination_file_name, 'r') as zip_ref:
        zip_ref.extractall(extract_path)
    
    os.environ['LD_LIBRARY_PATH'] = f"{extract_path}/lib:{os.environ.get('LD_LIBRARY_PATH', '')}"

def queryOracleDatabase(request):
    # 先初始化Oracle客户端库
    try:
        download_oracle_client()
    except Exception as e:
        print('Failed to initialize Oracle client: ', str(e))
        return

    # Oracle Database Connection
    username = 'x'
    password = 'y'
    connStr = '00.00.00.00:0000/abcd'
    try:
        conn = cx_Oracle.connect(username, password, connStr)
    except cx_Oracle.DatabaseError as e:
        error = e.args[0] if e.args else e
        print('Connection Error: ', error.message)
        return

    # Execute the query
    try:
        cursor = conn.cursor()
        cursor.execute('select * from table')  # 修正SQL语法错误
        data = cursor.fetchall()
    except cx_Oracle.DatabaseError as e:
        error = e.args[0] if e.args else e
        print('Query Error: ', error.message)
        return
    finally:
        # 确保资源被正确释放
        if 'cursor' in locals():
            cursor.close()
        if 'conn' in locals():
            conn.close()
    
    return data

4. 添加依赖包

在云函数的requirements.txt中添加所需依赖:

cx_Oracle>=8.0
google-cloud-storage>=2.0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:45:45