programing

Amazon Linux 환경에서 Python mariadb 모듈을 설치하는 방법

kingscode 2022. 11. 8. 21:23
반응형

Amazon Linux 환경에서 Python mariadb 모듈을 설치하는 방법

Python 3.8을 실행하는 AWS Lambdas용 mariadb 모듈을 공급할 AWS Lambda Layer를 구축하는 것이 목표입니다.

다음 절차에 따라 AWS Lambda 플랫폼과 호환되는 인스턴스에 mariadb 모듈을 설치해야 합니다.모듈을 이렇게 장착하면...

python3 -m pip install mariadb --target lambda-layer/python/lib/python3.8/site-packages

에러 메시지와 함께 실패...

mariadb_config not found.
Please make sure, that MariaDB Connector/C is installed on your system, edit the
configuration file 'site.cfg' and set the 'mariadb_config'
noption, which should point to the mariadb_config utility.

이 문제를 해결하려면 무엇이 필요합니까?

'MariaDB Connector/C'를 설치하는 것이 전제 조건입니까?하지만 어떻게 해야 하죠?AWS Lambda 레이어를 정의하는 데 사용할 수 있는 zip으로 패키징할 수 있는 방법은 무엇입니까?

일부 컨텍스트

Lamba 호스트와 동일한 Amazon 인스턴스에서 "Amazon Linux AMI 2018.03.0(HVM), SSD 볼륨 유형 - ami-02769748522663066"을 실행했습니다. cat /etc/os-release반환...

NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"

python3.8 Lambda Layer 패키징에는 다른 인스턴스 AMI가 더 좋을까요?

그리고 python3를 이것과 함께 셋업합니다(박스의 갤러리에는 python 3.8이 없습니다).

sudo yum install python36 -y

업데이트 및 자가 응답

즉, 현재로선 불가능하다는 것입니다.MariaDb Connector는 Linux의 Amazon 플레이버를 지원하지 않습니다.그러나 PyMySQL은 mariadb 서버에 연결할 대체 python 라이브러리가 있습니다.

다음은 람다용 AWS Function Layers를 제조하는 python3.8 AWS Lambda 함수의 내용입니다.

공장(AWS 람다)기능.

import json, boto3
from pathlib import Path
import os, sys, subprocess, shutil
from zipfile import ZipFile

def run( commandLine, captures, workingDir):
  options = {}
  if workingDir is not None:
    options['cwd'] = workingDir
  if 'standard-output' in captures:
    options['stdout'] = subprocess.PIPE
  if 'error-output' in captures:
    options['stderr'] = subprocess.PIPE
  proc = subprocess.run( commandLine, **options)
  outputLines = None
  errorLines  = None
  if 'standard-output' in captures:
    outputLines = proc.stdout.decode('UTF-8').strip().split( os.linesep)
  if 'error-output' in captures:
    errorLines = proc.stderr.decode('UTF-8').strip().split( os.linesep)
  if outputLines == ['']:
    outputLines = None
  if errorLines == ['']:
    errorLines = None
  return proc.returncode, outputLines, errorLines


def lambda_handler(event, context):
    request = json.loads( event['body'])
    sitePackages = '/tmp/aws-lambda-layer/lambda-layer/python/lib/python3.8/site-packages'
    Path( sitePackages).mkdir(parents=True, exist_ok=True)
    lines = request['requirements']
    print( lines)
    bucket      = request['bucket']
    packageKey  = request['key']
    ExtraArgs   = request.get('ExtraArgs')
    layerName   = request['layer-name']
    licenceInfo = request.get('license-info')
    requiresFN  = '/tmp/aws-lambda-layer/requirements.txt'
    origin      = os.environ.get( 'ORIGIN', '*')
    with open( requiresFN, 'w') as file: 
      file.writelines( lines)
    returncode, outputLines, errorLines = run(
      [sys.executable, '-m', 'pip', 'install', '-r', requiresFN, '--target',  sitePackages],
      ['standard-output','error-output'], '/tmp/aws-lambda-layer')
    base  = '/tmp/aws-lambda-layer/lambda-layer'
    zipFN = '/tmp/aws-lambda-layer/package.zip'
    l = len( base) + 1
    with ZipFile( zipFN, 'w') as package:
      for folderName, subfolders, filenames in os.walk( base):
        for filename in filenames:
          filePath = os.path.join( folderName, filename)
          path = filePath[l:]
          if os.path.basename( filePath) != 'yum.log':
            package.write( filePath, path)
    if ExtraArgs is None:
      ExtraArgs = {}
    ExtraArgs['ContentType'] = 'application/zip'
    runtime_region = os.environ.get('AWS_REGION')
    parms = {}
    if runtime_region is not None:
      parms['region_name'] = runtime_region
    s3Client     = boto3.client( 's3'    , **parms)
    lambdaClient = boto3.client( 'lambda', **parms)
    s3Client.upload_file( zipFN, bucket, packageKey, ExtraArgs)
    try:
      shutil.rmtree( '/tmp/aws-lambda-layer', ignore_errors=True) 
    except:
      print( 'Errors in cleaning up /tmp/aws-lambda-layer')
    description = 'python 3.8 requirements:' + '\n'.join( lines)
    parms = {'LayerName'  : layerName,
             'Description': description,
             'Content': { 'S3Bucket': bucket, 'S3Key': packageKey},
             'CompatibleRuntimes': ['python3.8']}
    if licenceInfo is not None:
      parms['LicenseInfo'] = licenceInfo
    try:
      response = lambdaClient.publish_layer_version( **parms)
      response = response['layer']['LayerVersionArn']
    except:
      print('Error in publishing.')
      response = None
    try:
      lambdaClient.delete_object( Bucket=bucket, Key=packageKey)
    except:
      print( 'Failure to delete s3 staging package.')
    statusCode = 200
    response = {'pip-return-code': returncode, 'out': outputLines,
                'err': errorLines, 'layer': response}
    ret = {'statusCode': statusCode,
           'body': json.dumps( response),
           'headers': {
             'Content-Type': 'application/json',
             'Access-Control-Allow-Credentials': 'true',
             'Access-Control-Allow-Origin': origin}}
    return ret

클라이언트측에서는, 이것을 (python script)라고 부릅니다.공장 함수는 python pip freeze 요건을 받아들여 지정된 모듈보다 많은 레이어를 제조합니다.제 경우, 요구 사항입니다.txt에는 PyMySQL이 포함됩니다.

import json
import boto3

# Config section. Adapt as required.
lambdaRegion = 'ap-southeast-2'
bucket = 'some-bucket'
key    = 'provisioning-workspace/layer-package.zip'
layerName = 'someLayerName'
filenm = 'some-path\\requirements.txt'
functionName = 'layer-factory-p38'
# End config section. 

parms = {}
if lambdaRegion is not None:
  parms['region_name'] = lambdaRegion

client = boto3.client( 'lambda', **parms)

def invoke( functionName, qualifier, inData):
  parms = {'FunctionName'  : functionName,
           'InvocationType': 'RequestResponse',
           'LogType'       : 'None',
           'Payload'       : str.encode( json.dumps( {'body': json.dumps( inData)}))}
  if qualifier is not None:
    parms['Qualifier'] = str( qualifier)
  response = client.invoke( **parms)
  response = json.loads( response['Payload'].read().decode('utf-8'))
  try:
    statusCode = int( response['statusCode'])
  except:
    statusCode = 0
  try:
    response = json.loads( response['body'])
  except:
    print( response)
    response = {}
  return statusCode, response

def buildLayer( factoryFunctionName, requirementsFN, layerName, bucket, key):
  with open( requirementsFN, 'r') as file: 
    lines = file.readlines()
  statusCode, response = invoke( factoryFunctionName, None, {
    'requirements': lines, 'bucket': bucket, 'key': key, 'layer-name': layerName})
  return response['layer']

layerArn = buildLayer( functionName, filenm, layerName, bucket, key)
print( layerArn)

언급URL : https://stackoverflow.com/questions/63277381/how-to-install-python-mariadb-module-in-an-amazon-linux-environment

반응형