python - 从 Google Cloud Function python3.7 连接到 Google Cloud SQL

标签 python google-cloud-platform google-cloud-functions google-cloud-sql pymysql

我正在尝试使用 pymysql 进行连接,使用的代码非常接近文档中提供的示例: https://cloud.google.com/functions/docs/sql#functions_sql_mysql-python

数据库有公共(public)IP,没有授权网络(因为cf应该使用套接字),并且我的用户创建允许从任何地方访问。

使用 Cloud SQL 代理在本地运行效果很好,但在 Google Cloud 上我连接被拒绝。

编辑:更新示例,其中包含使用环境变量在本地运行的代码

import logging
import os

import pymysql
from pymysql.err import OperationalError


mysql_conn = None


def __get_cursor():
    try:
        return mysql_conn.cursor()
    except OperationalError:
        mysql_conn.ping(reconnect=True)
        return mysql_conn.cursor()


def get_config():
    return {
        'unix_socket': f'/cloudsql/{os.environ["CONNECTION_NAME"]}',
        'user': os.environ['DB_USER'],
        'password': os.environ['DB_PASSWORD'],
        'db': os.environ['DB_NAME'],
        'charset': 'utf8mb4',
        'cursorclass': pymysql.cursors.DictCursor,
        'autocommit': True
    }


def mysql_demo(request):
    global mysql_conn

    if not mysql_conn:
        mysql_config = get_config()
        logging.info('Open db with config: %s', mysql_config)

        try:
            mysql_conn = pymysql.connect(**mysql_config)
        except OperationalError as exception:
            logging.warning('Unable to get db connection: %s', str(exception))
            return

    with __get_cursor() as cursor:
        cursor.execute('SELECT NOW() as now')
        results = cursor.fetchone()
        return str(results['now'])


if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    os.environ['CONNECTION_NAME'] = 'my-project:us-central1:cf-test'
    os.environ['DB_USER'] = 'db-user'
    os.environ['DB_PASSWORD'] = 'db-password'
    os.environ['DB_NAME'] = 'db_name'
    logging.info(mysql_demo(None))

编辑:附加输出

本地运行时,打印出:

INFO:root:2019-09-24 07:11:54

作为云函数运行时,我得到输出:`

2019-09-24 09:14:59.279 CEST test-cloud-sql mesuju89uxuw Open db with config: {'unix_socket': '/cloudsql/boeingfda-jal:us-central1:cf-test', 'user': 'enplore', 'password': 'az2labha', 'db': 'content_enplore_auth', 'charset': 'utf8mb4', 'cursorclass': <class 'pymysql.cursors.DictCursor'>, 'autocommit': True}
2019-09-24 09:14:59.856 CEST test-cloud-sql mesuju89uxuw Unable to get db connection: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")

最佳答案

如果您发布收到的错误,通常会更有帮助,因为它通常会提供额外的上下文。以下是一些可能的原因:

  • 确保 Cloud SQL Admin API 已启用。
  • 验证您用于运行实例的服务帐户(默认为 service-[YOUR_PROJECT_NUMBER]@gcf-admin-robot.iam.gserviceaccount.com)是否具有正确的 IAM 权限 (Cloud SQL Client 角色或 cloudsql.instances.connectcloudsql.instances.get 权限)。
  • 最后,验证 CONNECTION_NAME 变量没有拼写错误。

最后,您应该考虑使用连接池(如 SQLAlchemy)并将最大限制设置为 1。连接池将更优雅地处理错误,并限制每个实例使用的连接数。

关于python - 从 Google Cloud Function python3.7 连接到 Google Cloud SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58065493/

相关文章:

python - 对于 : not returning all lines 中的行

mongodb - Google Cloud Datastore 是否真的在执行其 1MB 的实体大小限制?

firebase - 如何在 Firebase 函数中获取下载 URL

python - 路易吉 : Rangehourly Examples

python - 需要一些关于 python 中的 Cookie 处理和 session 的帮助

reactjs - 在 Google Kubernetes 上设置 react app build 文件夹

c# - 为什么 Google.Pubsub.V1 beta01 不适用于 dotnet cli 项目?

unit-testing - Firebase 函数 TypeScript 单元测试 devDependencies

google-maps - 带有 Google Maps API 的云函数

python - 不能在 Celery 中使用 SQLite 作为后端