簡體   English   中英

如何讓 Django 連接到 SQL 服務器與 AWS Lambda 層一起使用?

[英]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所需的共享庫libltdllibodbc ),但在 lambda 環境中通常不可用。

創建圖層

該層將具有django==2.2.12django-mssql-backendpyodbc

# 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 設置為兼容的運行時。

使用您的 function 創建 lambda 部署 package

在您的主機上執行

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.

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