访问PostgreSQL数据库是指在函数计算中通过函数调用数据库应用编程接口,对数据库执行数据插入、查询等操作。通常函数计算中不同的执行环境实例之间的状态是不共享的,通过数据库的形式可以将结构化的数据持久化以实现状态共享。本文介绍如何通过Funcraft部署函数来访问PostgreSQL数据库。

前提条件

  1. 创建专有网络和交换机

    创建的交换机需要在函数计算支持的可用区内,函数计算支持的可用区信息请参见配置VPC功能

  2. 创建RDS PostgreSQL实例

    创建数据库实例需要选择与函数计算相同的VPC实例。由于相同的VPC实例下不同可用区交换机内网是互通的,因此您可以配置和函数计算不同可用区的交换机。

  3. 设置白名单

    如果您通过设置白名单分组的方法来设置数据库白名单,则需要在设置过程中的组内白名单文本框中输入相应的VPC的IPv4网段。您可以登录VPC控制台,进入目标VPC的专有网络详情页查看VPC的IPv4网段。

  4. 创建安全组

    安全组出口方向必须放行数据库的端口和内网IP段。

背景信息

访问PostgreSQL的原理、工作机制与访问MySQL数据库相同,详情请参见访问MySQL数据库

编写函数

本文以Python3开发语言的函数示例为例,介绍如何通过Funcraft工具编写函数访问数据库。

  1. 在本地建立一个目录,用于存放代码和依赖模块,在该目录下新建template.yml文件,例如/tmp/code/template.yml,示例内容如下。
    ROSTemplateFormatVersion: '2015-09-01'
    Transform: 'Aliyun::Serverless-2018-04-03'
    Resources:
      service:
        Type: 'Aliyun::Serverless::Service'
        Properties:
          Description: This is PostgreSQL service
          Policies:
            - AliyunECSNetworkInterfaceManagementAccess      
          VpcConfig:
            VpcId: vpc-****
            VSwitchIds:
              - vsw-***
            SecurityGroupId: sg-***
          InternetAccess: true
        function:
          Type: 'Aliyun::Serverless::Function'
          Properties:
            Handler: 'index.handler'
            Initializer: 'index.initializer'
            Runtime: python3
            Timeout: 10
            MemorySize: 128
            CodeUri: './'
            EnvironmentVariables:
              HOST: pgm-bp1yawvyyu***.pg.rds.aliyuncs.com
              PASSWORD: Txd123**
              PORT: 1433
              DATABASE: test_123
              USER: ***

    代码中的关键参数含义如下:

    • 声明了一个名为service的服务。
      • Policies: 授予函数计算管理ECS弹性网卡的权限,实现函数服务访问在已创建的VPC内的资源。
      • VpcConfig:为服务绑定已创建的VPC。您需要将以下参数值替换成自己的VPC相关信息。
        • VpcId:专有网络ID。
        • VSwitchIds:交换机ID。
        • SecurityGroupId:安全组ID。
    • 声明了一个名为function的函数。
      • Initializer:函数初始化入口。
      • Handler:函数入口。
      • Runtime:函数的运行环境。
      • CodeUri:代码包所在的目录。

        部署时,Funcraft会将CodeUri指定的目录打包上传。

      • EnvironmentVariables:配置函数环境变量。
        • HOST:内网链接地址。

          登录RDS管理控制台,单击目标实例进入基本信息页面,在基本信息区域查看内网地址

        • PASSWORD:数据库登录密码。
        • PORT:数据库端口。
        • DATABASE:数据库名称。
        • USER:登录数据库的用户名。
  2. template.yml文件的同级目录下创建Funfile文件,示例内容如下。
    RUNTIME python3
    RUN fun-install pip install psycopg2
  3. 执行fun install命令安装依赖。
    fun install
    当代码编辑器出现以下打印内容时,说明安装成功。
    Install Success
  4. template.yml文件的同级目录下新建代码文件,例如/tmp/code/index.py,示例内容如下。
    # -*- coding: utf-8 -*-
    import logging
    import psycopg2
    import os,sys
    logger = logging.getLogger()
    
    def getConnection():
      try:
        conn = psycopg2.connect(
          database = os.environ['DATABASE'],
          user = os.environ['USER'],
          password = os.environ['PASSWORD'],
          host = os.environ['HOST'],
          port = os.environ['PORT'],
          )
        return conn
      except Exception as e:
        logger.error(e)
        logger.error("ERROR: Unexpected error: Could not connect to PostgreSQL instance.")
        sys.exit()
    
    def conditionallyCreateUsersTable():
        conn = getConnection()
        cur = conn.cursor()
        cur.execute('''CREATE TABLE COMPANY
            (ID INT PRIMARY KEY     NOT NULL,
            NAME           TEXT    NOT NULL,
            AGE            INT     NOT NULL,
            ADDRESS        CHAR(50),
            SALARY         REAL);''')
        conn.commit()
        conn.close()
    
    def initializer(context):
      conditionallyCreateUsersTable()
    
    def handler(event, context):
      try:
        conn = getConnection()
        cur = conn.cursor()
        cur.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \
          VALUES (1, 'Paul', 32, 'California', 20000.00 )");
        conn.commit()
        return 'successfully'
      finally:
        conn.close()
  5. 执行以下命令,使用Funcraft工具部署。
    fun deploy -y
    当代码编辑器出现以下打印内容时,说明部署成功。
            function <function-name> deploy success
    service <service-name> deploy success

调试函数

  1. 登录函数计算控制台
  2. 在顶部菜单栏,选择地域。
  3. 在左侧导航栏,单击服务/函数
  4. 找到目标服务下的目标函数,单击函数名称。
  5. 单击代码执行页签,然后单击执行
    当前页面返回正确的结果,则说明函数调试成功。result