[英]How do I get Django connecting to SQL Server working with AWS Lambda Layers?
I am trying to use Django connected to SQL Server 2019 in an AWS Lambda function using Lambda Layers. 我在這里找到了一個使用 pyodbc 連接到 SQL 服務器的示例: https://medium.com/@kuharan/aws-lambda-python-ms-sql-server-the-easy-way-e7667d371cc5 。
我下載了示例 Lambda 層和 Lambda function 並且能夠使其正常工作。 However, now I am trying to install Django and django-mssql-backend in the layer in order to use Django to connect to SQL Server 2019. Here is a screenshot of how the directory structure is setup with Django and django-mssql-backend installed :
我壓縮了pyodbc-layers
文件夾並將其上傳到 Layers。 這是一個截圖:
然后,當我運行 lambda function 時,出現錯誤:
Response:
{
"errorMessage": "Unable to import module 'lambda_function': No module named 'django'",
"errorType": "Runtime.ImportModuleError"
}
這是我的 function 的屏幕截圖和錯誤消息:
我該如何解決這個問題? 謝謝!
編輯:
這是我所有的文本代碼:
lambda_function.py:
import json
import os
from datetime import datetime, timedelta
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
django.setup()
from models.models import Schedule
def lambda_handler(event, context):
games = Schedule.objects.using('default').filter(
game_date=(
datetime.today() - timedelta(days=1)
).date().strftime('%Y-%m-%d')
).values()
print(games)
設置.py:
DEBUG = True
DATABASE_HOSTNAME = 'some_host'
DATABASE_USER = 'some_user'
DATABASE_PASSWORD = 'some_password'
DRIVER = 'ODBC Driver 17 for SQL Server'
SECRET_KEY = 'some_key'
DATE_INPUT_FORMATS = '%Y-%m-%d'
INSTALLED_APPS = (
'models',
)
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'NAME': 'database_name',
'ENGINE': 'sql_server.pyodbc',
'HOST': DATABASE_HOSTNAME,
'USER': DATABASE_USER,
'PASSWORD': DATABASE_PASSWORD,
'OPTIONS': {
'driver': DRIVER,
'isolation_level': 'READ UNCOMMITTED'
},
}
}
模型.models.py:
from django.db import models
class Schedule(models.Model):
game_id = models.IntegerField(primary_key=True)
game_date = models.DateField()
class Meta:
app_label = 'models'
managed = True
db_table = 'Schedule'
使用此代碼和 lambda 層構建的完整錯誤消息如下:
{
"errorMessage": "('IM002', '[IM002] [unixODBC][Driver Manager]Data source name not found, and no default driver specified (0) (SQLDriverConnect)')",
"errorType": "InterfaceError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 20, in lambda_handler\n print(games)\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/models/query.py\", line 250, in __repr__\n data = list(self[:REPR_OUTPUT_SIZE + 1])\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/models/query.py\", line 274, in __iter__\n self._fetch_all()\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/models/query.py\", line 1242, in _fetch_all\n self._result_cache = list(self._iterable_class(self))\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/models/query.py\", line 113, in __iter__\n for row in compiler.results_iter(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size):\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/models/sql/compiler.py\", line 1092, in results_iter\n results = self.execute_sql(MULTI, chunked_fetch=chunked_fetch, chunk_size=chunk_size)\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/models/sql/compiler.py\", line 1127, in execute_sql\n sql, params = self.as_sql()\n",
" File \"/opt/python/lib/python3.7/site-packages/sql_server/pyodbc/compiler.py\", line 177, in as_sql\n supports_offset_clause = self.connection.sql_server_version >= 2012\n",
" File \"/opt/python/lib/python3.7/site-packages/django/utils/functional.py\", line 80, in __get__\n res = instance.__dict__[self.name] = self.func(instance)\n",
" File \"/opt/python/lib/python3.7/site-packages/sql_server/pyodbc/base.py\", line 400, in sql_server_version\n with self.temporary_connection() as cursor:\n",
" File \"/var/lang/lib/python3.7/contextlib.py\", line 112, in __enter__\n return next(self.gen)\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/backends/base/base.py\", line 593, in temporary_connection\n with self.cursor() as cursor:\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/backends/base/base.py\", line 256, in cursor\n return self._cursor()\n",
" File \"/opt/python/lib/python3.7/site-packages/sql_server/pyodbc/base.py\", line 218, in _cursor\n conn = super()._cursor()\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/backends/base/base.py\", line 233, in _cursor\n self.ensure_connection()\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/backends/base/base.py\", line 217, in ensure_connection\n self.connect()\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/utils.py\", line 89, in __exit__\n raise dj_exc_value.with_traceback(traceback) from exc_value\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/backends/base/base.py\", line 217, in ensure_connection\n self.connect()\n",
" File \"/opt/python/lib/python3.7/site-packages/django/db/backends/base/base.py\", line 195, in connect\n self.connection = self.get_new_connection(conn_params)\n",
" File \"/opt/python/lib/python3.7/site-packages/sql_server/pyodbc/base.py\", line 314, in get_new_connection\n timeout=timeout)\n"
]
}
我使用docker 工具為python 3.8
創建了自定義層。 該指令適用於 linux,因為我沒有 windows 進行測試。 盡管如此,這些步驟可以適應 windows。
主要困難在於odbc
所需的共享庫( libltdl
和libodbc
),但在 lambda 環境中通常不可用。
該層將具有django==2.2.12
、 django-mssql-backend
和pyodbc
。
# create layer folder on your host operating system
mkdir /tmp/layer1
# run dcoker container for lambda python 3.8
docker run --rm -v /tmp/layer1:/tmp/layer1 -ti lambci/lambda:build-python3.8 /bin/bash
# in the container exectue the following commands
cd /tmp/layer1
yum install -y unixODBC-devel
python -m venv python
source ./python/bin/activate
pip install django==2.2.12 django-mssql-backend pyodbc
zip -r django-odbc.zip .
cp -rvf /usr/lib64/libltdl.so* .
cp -rvf /usr/lib64/libodbc.so* .
使用 django-odbc.zip 創建一個層,記住將 python3.8 設置為兼容的運行時。
在您的主機上執行
mkdir /tmp/lambda_function
cd /tmp/lambda_function
cp -rvf /tmp/layer1/*.so* .
還要添加以下文件lambda_function.py
:
import json
import django
import pyodbc
def lambda_handler(event, context):
# TODO implement
print(django.get_version())
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
進行部署 package:
zip -r lambda_function.zip .
使用lambda_function.zip
並添加層django-odbc.zip
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.