簡體   English   中英

從 AWS Lambda 連接 Oracle

[英]Connect Oracle from AWS Lambda

我有一個 Lambda function 需要使用 pandas、ZF3D386AADEEB6063D016E4_Oracle56026

將所有這些庫安裝和打包在一起超過了AWS Lambda 的 250MB 部署 package 限制

我想只包括 Z3 0162ED78B6C10F731411F2FC440C24FZ Basic Light Package的 zip ,然后在運行時提取並使用它。

我試過的

我的項目結構如下:

cx_Oracle-7.2.3.dist-info/
dateutil/
numpy/
pandas/
pytz/six-1.12.0.dist-info/
sqlalchemy/
SQLAlchemy-1.3.8.egg-info/
cx_Oracle.cpython-36m-x86_64-linux-hnu.so
instantclient-basiclite-linux.x64-19.3.0.0.0dbru.zip
main.py
six.py
template.yml

main.py中,我運行以下命令:

import json, traceback, os

import sqlalchemy as sa
import pandas as pd

def main(event, context):
    try:
        unzip_oracle()
        return {'statusCode': 200,
                'body': json.dumps(run_query()),
                'headers': {'Content-Type': 'application/json', 'Access-Control-Allow-Origin':'*'}}
    except:
        em = traceback.format_exc()
        print("Error encountered. Error is: \n" + str(em))
        return {'statusCode': 500,
                'body': str(em),
                'headers': {'Content-Type': 'application/json', 'Access-Control-Allow-Origin':'*'}}  



def unzip_oracle():
    print('extracting oracle drivers and copying results to /var/task/lib')
    os.system('unzip /var/task/instantclient-basiclite-linux.x64-19.3.0.0.0dbru.zip -d /tmp')
    print('extraction steps complete')
    os.system('export ORACLE_HOME=/tmp/instantclient_19_3')


def get_db_connection():
    return sa.engine.url.URL('oracle+cx_oracle', 
        username='do_not_worry', password='about_any', 
        host='of_these', port=1521, 
        query=dict(service_name='details')
    )


def run_query():
    query_text = """SELECT * FROM dont_worry_about_it"""
    conn = sa.create_engine(get_db_connection())
    print('Connected')
    df = pd.read_sql(sa.text(query_text), conn)
    print(df.shape)
    return df.to_json(orient='records')

這將返回錯誤:

sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) DPI-1047: 找不到 64 位 Oracle 客戶端庫:“libclntsh.so:無法打開共享的 ZA8CFDE6331BD59EB2ACZF 文件:” 請參閱https://oracle.github.io/odpi/doc/installation.html#linux獲取幫助(此錯誤的背景位於: http6://sql.cheme//

我也嘗試過的

我試過了:

  • 添加
Environment: 
    Variables: 
      ORACLE_HOME: /tmp 
      LD_LIBRARY_PATH: /tmp 

template.yml並重新部署。 與上述相同的錯誤。

  • os.system('export LD_LIBRARY_PATH=/tmp/instantclient_19_3')添加到 python 腳本中。 與上述相同的錯誤。
  • 許多cpln/tmp文件夾之外的 Lambda 中被禁止。 與上述相同的錯誤。

一種有效但不好的方法

如果我在 Lambda package 中創建一個名為lib/的文件夾,並包含一個奇怪的分類libaio.so.1libclntsh.so等文件, ZC1C425268E68385D1AB5074C1 將按預期工作 我最終得到了這個:

<all the other libraries and files as above>
lib/
-libaio.so.1
-libclntsh.so
-libclntsh.so.10.1
-libclntsh.so.11.1
-libclntsh.so.12.1
-libclntsh.so.18.1
-libclntsh.so.19.1
-libclntshcore.so.19.1
-libipc1.so
-libmql1.so
-libnnz19.so
-libocci.so
-libocci.so.10.1
-libocci.so.11.1
-libocci.so.12.1
-libocci.so.18.1
-libocci.so.19.1
-libociicus.so
-libons.so

但是,我通過反復試驗選擇了這些文件,不想再通過這個 go。

Is there a way to unzip instantclient-basiclite-linux.x64-19.3.0.0.0dbru.zip in Lambda at runtime, and make Lambda see/use it to connect to an Oracle database?

我絕不是 python 的專家,但這條線似乎很奇怪

print('extracting oracle drivers and copying results to /var/task/lib')
os.system('unzip /var/task/instantclient-basiclite-linux.x64-19.3.0.0.0dbru.zip -d /tmp')
print('extraction steps complete')
os.system('export ORACLE_HOME=/tmp/instantclient_19_3')

通常,您對操作系統級別 API 和 Lambda 的訪問權限非常有限。 即使你這樣做了,它也可以按照你不希望它做的方式行事。 (想像:誰擁有“解壓縮”功能?此命令創建的文件將由誰可見/可調用?)

我看到您提到提取文件沒有問題,這也有點奇怪

我給你的唯一答案是

1/ 嘗試“自帶”工具(解壓縮等)

2/ 永遠不要嘗試進行操作系統級別的調用。 和 os.system('export...') 一樣,總是使用完整路徑

再次查看您的問題,您指定環境變量的方式似乎有沖突

ORACLE_HOME: /tmp 

不應該

Environment: 
    Variables: 
      ORACLE_HOME: /tmp/instantclient_19_3
      LD_LIBRARY_PATH: /tmp/instantclient_19_3

另請參閱: 如何從 Python 訪問 AWS Lambda 環境變量

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM