Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Google云函数python3.7连接到Google云SQL_Python_Google Cloud Platform_Google Cloud Functions_Google Cloud Sql_Pymysql - Fatal编程技术网

从Google云函数python3.7连接到Google云SQL

从Google云函数python3.7连接到Google云SQL,python,google-cloud-platform,google-cloud-functions,google-cloud-sql,pymysql,Python,Google Cloud Platform,Google Cloud Functions,Google Cloud Sql,Pymysql,我尝试使用pymysql进行连接,使用的代码与文档中提供的示例非常接近: 数据库有公共ip,没有经过授权的网络(因为cf应该使用套接字),我的用户创建的数据库允许从任何地方访问 使用云SQL代理在本地运行效果很好,但在谷歌云上,我的连接被拒绝 编辑:使用代码更新了示例,以便使用env vars在本地运行 import logging import os import pymysql from pymysql.err import OperationalError mysql_conn =

我尝试使用pymysql进行连接,使用的代码与文档中提供的示例非常接近:

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

使用云SQL代理在本地运行效果很好,但在谷歌云上,我的连接被拒绝

编辑:使用代码更新了示例,以便使用env vars在本地运行

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)")
2019-09-24 09:14:59.279 CEST测试云sql mesuju89uxuw开放数据库,配置:{'unix_socket':'/cloudsql/boeingfda jal:us-central1:cf test','user':'enplore','password':'az2labha','db':'content_enplore_auth','charset':'utf8mb4','cursorclass','autocommit':True}
2019-09-24 09:14:59.856 CEST测试云sql mesuju89uxuw无法获得数据库连接:(2003,“无法连接到“localhost”上的MySQL服务器([Errno 111]连接被拒绝)”)

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

  • 确保启用了云SQL管理API
  • 验证用于运行实例的服务帐户(默认为
    service-[YOUR_PROJECT\u NUMBER]@gcf admin robot.iam.gserviceaccount.com
    )是否具有正确的iam权限(
    Cloud SQL Client
    角色或
    cloudsql.instances.connect
    cloudsql.instances.get
    权限)
  • 最后,验证
    CONNECTION\u NAME
    变量是否拼写错误

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

看起来您的unix\u套接字项没有正确生成。它接受以下格式的数据:

'/cloudsql/project-id:region:instance-name'
例如:

'/cloudsql/my-awesome-project:us-central1:mysqlinst1'
要获得确切的连接名称,可以使用以下命令:

gcloud sql instances describe <instance_name> | grep connectionName
gcloud sql实例描述| grep connectionName

就像调试一样。。。1) 确认您正在云SQL上使用第二代MySQL实例,对吗?2) 打印输出:{CONNECTION_NAME}。只是为了确保它在GCF的环境中被正确设置。如果您在控制台中作为测试运行该函数,您应该会看到STDOUT.1的任何输出。数据库实例已验证为第二代2。完整的mysql配置已打印并验证,以使用正确的unix_套接字(/cloudsql/*redact*:us-central1:cf test)、用户、密码和数据库。3.在本地运行该函数,并启动云SQL代理时,我可以获得今天日期和时间的预期输出。谢谢,这确实是我的原因,我错过了将云SQL客户端权限添加到云函数的服务帐户。很高兴我能帮上忙!