使用 Alembic 框架在 AWS Lambda 中运行数据库迁移

问题描述 投票:0回答:1

只是这个问题的后续问题

我已将应用程序部署到AWS Lambda,它与RDS数据库PostgreSQL配合使用,API网关调用Lambda来处理外部请求,例如

GET /api/endpoint

当前数据库迁移/应用程序更新流程:

0 - 之前的App代码部署在Lambda中,里面有ORM,与DB一起工作,Lambda由API网关调用

1 - 在 CI/CD 数据库迁移中,Lambda 在部署期间执行,它更新数据库架构

2 - 在 CI/CD 中部署更新版本的应用程序,与更新的数据库架构兼容。

问题出在部署的 Lambda 中的步骤 1 和 2 代码之间,有时它与更新的数据库架构不兼容,从而导致数据库查询错误。

有什么建议如何克服这个停机时间窗口吗?

aws-lambda database-migration alembic
1个回答
0
投票

我正在采用类似的方法:

  1. 执行业务逻辑的 lambda
  2. sqlalchemy 层(+模型定义)
  3. 另一个 lambda,每次管道检测到该层文件夹上的新更改时都会执行数据库迁移

所以: 为了使用 SAM 部署第一个 lambda im,它包含一个指示层版本的参数(我们将此文件称为 template.yaml):

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters:
    LayerVersion:
        Type:String

然后我从业务逻辑 lambda 中引用它:

  LambdaExample:
    Type: AWS::Serverless::Function
    Properties:
      Role: !GetAtt LambdaRole.Arn
      FunctionName: lambdaexample
      CodeUri: ./functions/lambda_example
      Handler: lambda_function.lambda_handler
      Runtime: python3.9
      Timeout: 15
      Environment:
        Variables:
          DB_SECRET_NAME: !Ref SecretNameExample
      VpcConfig:
        SubnetIds: 
          - !Ref LambdaSubnetId1
          - !Ref LambdaSubnetId2
        SecurityGroupIds: 
          - !Ref LambdaSecurityGroupId
      Layers:
        - !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:database-layer:${LayerVersion}

对于层和迁移 lambda,我有另一个 sam 模板,为什么?因为我想在部署任何使用它的 lambda 之前更新数据库模型,并避免在引用最新层版本而不迁移它时可能发生的故障

所以:这是layer-template.yaml的示例(省略角色创建等)

DatabaseLayer:
    Type: AWS::Serverless::LayerVersion
    Name: 'database-layer'
    Properties:
      LayerName: 'database-layer'
      ContentUri: ./database-example
      CompatibleRuntimes:
        - python3.9
    Metadata:
      BuildMethod: python3.9

MigrateDatabaseFunction:
    Type: AWS::Serverless::Function
    Properties:
      Role: !GetAtt MigrateDBRole.Arn
      FunctionName: automigrate-database
      CodeUri: ./automigrate-database
      Handler: lambda_function.lambda_handler
      Runtime: python3.9
      Timeout: 120
      MemorySize: 2048
      Layers:
        - !Ref DatabaseLayer
      Environment:
        Variables:
          SECRET_NAME: !Ref SecretNameExample
      VpcConfig:
        SubnetIds: 
          - !Ref LambdaSubnetId1
          - !Ref LambdaSubnetId2
        SecurityGroupIds: 
          - !Ref LambdaSecurityGroupId

从现在开始ci/cd应该做什么? 每次它检测到文件夹数据库示例的更改时,它都应该调用 MigrateDatabaseFunction:

  • 构建您的layer/layer-template.yaml并部署它
  • 执行数据库模型文件的 git diff(如果已更改):
  • 执行 aws lambda invoke --function-name automigrate-datbase --region {{your_region}} 并将结果保存在文件中,以便您可以检查它是否失败
  • 如果没有失败,您可以使用新层版本的参数构建和部署 template.yaml
© www.soinside.com 2019 - 2024. All rights reserved.