use*_*159 5 python oracle amazon-web-services aws-lambda
我有一个需要使用 Pandas、sqlalchemy 和 cx_Oracle 的 Lambda 函数。
将所有这些库安装和打包在一起超过了AWS Lambda的250MB 部署包限制。
我只想包含Oracle 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
Run Code Online (Sandbox Code Playgroud)
在 中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')
Run Code Online (Sandbox Code Playgroud)
这将返回错误:
sqlalchemy.exc.DatabaseError:(cx_Oracle.DatabaseError) DPI-1047:找不到 64 位 Oracle 客户端库:“libclntsh.so:无法打开共享对象文件:没有这样的文件或目录”。请参阅https://oracle.github.io/odpi/doc/installation.html#linux寻求帮助(此错误的背景:http : //sqlalche.me/e/4xp6)
我也尝试过
我试过了:
Environment:
Variables:
ORACLE_HOME: /tmp
LD_LIBRARY_PATH: /tmp
Run Code Online (Sandbox Code Playgroud)
到template.yml并重新部署。和上面一样的错误。
os.system('export LD_LIBRARY_PATH=/tmp/instantclient_19_3')到python脚本中。和上面一样的错误。cp和ln事物/tmp。和上面一样的错误。一种有效但不好的方法
如果我做一个文件夹,名为lib/在lambda包,包括一个奇特的组合libaio.so.1,libclntsh.so等文件,该功能可以发挥预期的,由于某种原因。我结束了这个:
<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
Run Code Online (Sandbox Code Playgroud)
但是,我通过反复试验选择了这些文件,不想再经历一遍。
有没有办法instantclient-basiclite-linux.x64-19.3.0.0.0dbru.zip在运行时在 Lambda 中解压缩,并让 Lambda 看到/使用它来连接到 Oracle 数据库?
我无论如何都不是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')
Run Code Online (Sandbox Code Playgroud)
通常,您使用 Lambda 对操作系统级 API 的访问权限非常有限。即使你这样做了,它也可能会按照你不期望的方式行事。(想象一下:谁拥有“解压缩”功能?由该命令创建的文件将由谁可见/调用?)
我看到你提到你提取文件没有问题,这也有点奇怪
我对你唯一的回答是
1/尝试“自带”工具(解压等)
2/ 切勿尝试进行操作系统级别的调用。像 os.system('export ...') 一样,始终使用完整路径
再次查看您的问题,似乎您指定环境变量的方式存在冲突
ORACLE_HOME: /tmp
Run Code Online (Sandbox Code Playgroud)
不应该是这样吗
Environment:
Variables:
ORACLE_HOME: /tmp/instantclient_19_3
LD_LIBRARY_PATH: /tmp/instantclient_19_3
Run Code Online (Sandbox Code Playgroud)
另请参阅:如何从 Python 访问 AWS Lambda 环境变量
| 归档时间: |
|
| 查看次数: |
1259 次 |
| 最近记录: |