Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.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
Python 云存储桶的云SQL导入权限问题_Python_Google Cloud Platform_Google Cloud Storage_Google Cloud Functions_Google Cloud Sql - Fatal编程技术网

Python 云存储桶的云SQL导入权限问题

Python 云存储桶的云SQL导入权限问题,python,google-cloud-platform,google-cloud-storage,google-cloud-functions,google-cloud-sql,Python,Google Cloud Platform,Google Cloud Storage,Google Cloud Functions,Google Cloud Sql,我正在编写一个云函数来: 云存储桶中文件的云SQL(postgresql)数据库 它返回到另一个云SQL实例/DB(仍然是postgresql) 注意: 我想让这段代码每晚独立运行,将生产数据库复制到登台环境,所以我计划使用云调度程序触发它。 如果您有更好/更简单的解决方案在GCP中解决此问题,我洗耳恭听:) 这是我的代码(实际函数是文件底部的clone\u db): 从操作系统导入getenv 从日期时间导入日期时间 从时间上导入睡眠 从GoogleAppClient导入发现 从Googl

我正在编写一个云函数来:

  • 云存储桶中文件的云SQL(postgresql)数据库
  • 它返回到另一个云SQL实例/DB(仍然是postgresql)
注意: 我想让这段代码每晚独立运行,将生产数据库复制到登台环境,所以我计划使用云调度程序触发它。
如果您有更好/更简单的解决方案在GCP中解决此问题,我洗耳恭听:)

这是我的代码(实际函数是文件底部的
clone\u db
):

从操作系统导入getenv
从日期时间导入日期时间
从时间上导入睡眠
从GoogleAppClient导入发现
从GoogleAppClient.errors导入HttpError
从oauth2client.client导入Google凭据
从google.cloud导入存储
GS_BUCKET=getenv(“GS_BUCKET”)
GS_FOLDER=“sql导出”
GS_EXPORT_PATH=f“GS://{GS_BUCKET}/{GS_FOLDER}”
定义sql文件名(db:str,时间戳:datetime):
返回f“{db}-{timestamp.strftime(“%Y-%m-%d')}.sql.gz”
定义sql文件uri(db:str,时间戳:datetime):
返回f“{GS_EXPORT_PATH}/{{sql_file_name(db,timestamp)}”
定义导出源数据库(服务,项目:str,时间戳:datetime,实例:str,数据库:str):
上下文={
“导出上下文”:{
“种类”:“sql#导出上下文”,
“文件类型”:“SQL”,
“uri”:_uSQL_u文件u uri(db,时间戳),
“数据库”:[db],
}
}
return service.instances().export(project=project,instance=instance,body=context).execute()
定义导入目标数据库(服务,项目:str,时间戳:datetime,实例:str,数据库:str):
上下文={
“导入上下文”:{
“种类”:“sql#importContext”,
“文件类型”:“SQL”,
“uri”:_uSQL_u文件u uri(db,时间戳),
“数据库”:db,
}
}
return service.instances()
def-drop-db(服务,项目:str,实例:str,db:str):
尝试:
return service.databases().delete(project=project,instance=instance,database=db).execute()
除HttpError作为e外:
如果e.resp.status==404:
返回{“状态”:“完成”}
其他:
提高e
定义创建数据库(服务,项目:str,实例:str,数据库:str):
数据库={
“名称”:db,
“项目”:项目,
“实例”:实例,
}
return service.databases().insert(project=project,instance=instance,body=database).execute()
定义更新导出权限(文件名:str):
client=storage.client()
file=client.get_bucket(GS_bucket).get_blob(f“{GS_FOLDER}/{file_name}”)
file.acl.user(getenv(“TARGET\u DB\u SERVICE\u ACCOUNT”)).grant\u read()
file.acl.save()文件
定义删除sql文件(文件名:str):
client=storage.client()
bucket=client.get\u bucket(GS\u bucket)
delete_blob(f“{GS_FOLDER}/{file_name}”)
定义等待(操作类型、操作、服务、项目):
如果操作[“状态”]处于(“挂起”、“运行”、“未知”):
打印(f“{operation['status']}状态下的{operation_type}操作。正在等待完成…”)
操作时[“状态”]!=“完成”:
睡眠(1)
operation=service.operations().get(project=project,operation=operation['name']).execute()
打印(f“{operation\u type}操作已完成!”)
def clone_db(u):
credentials=GoogleCredentials.get_application_default()
service=discovery.build('sqladmin','v1beta4',credentials=credentials)
#包含要导出的实例的项目的项目ID。
project=getenv('project\u ID')
#云SQL实例ID。这不包括项目ID。
来源={
“实例”:getenv(“源实例ID”),
“db”:getenv(“源数据库名称”)
}
timestamp=datetime.utcnow()
打印(f“正在将数据库{source['instance']}:{source['db']}导出到云存储…”)
操作=\导出\源\数据库(服务、项目、时间戳,**源)
__等待(出口、运营、服务、项目)
打印(“更新导出的文件权限…”)
__更新导出权限(sql文件名(源[“db”],时间戳))
打印(“完成”)
目标={
“实例”:getenv(“目标实例ID”),
“db”:getenv(“TARGET\u db\u NAME”)
}
打印(f“正在删除目标数据库{target['instance']}:{target['db']}”)
操作=\删除\数据库(服务、项目、**目标)
__等待(删除、操作、服务、项目)
打印(f“正在创建数据库{target['instance']}:{target['db']}…”)
操作=\创建\数据库(服务、项目、**目标)
__等待(创建、操作、服务、项目)
打印(f“将数据导入{target['instance']}:{target['db']}…”)
操作=\导入\目标\数据库(服务、项目、时间戳,**目标)
__等待(导入、操作、服务、项目)
打印(“删除导出的SQL文件”)
__删除sql文件(sql文件名(源[“db”],时间戳))
打印(“完成”)
在我尝试将导出的数据导入目标实例之前,一切都非常顺利

在调用
导入时
,函数失败,出现以下错误:

Error: function crashed. Details:
<HttpError 403 when requesting https://www.googleapis.com/sql/v1beta4/projects/<project_id>/instances/<instance_id>/import?alt=json returned "The service account does not have the required permissions for the bucket.">

错误:函数崩溃。细节:
我在这里和网络上的许多其他问答中都读到了这个错误,但我不知道如何使事情正常进行。
以下是我所做的:

  • 云函数作为我的“计算引擎默认服务帐户”运行,该帐户在IAM中设置了
    项目编辑器
    角色
  • 目标云SQL实例的服务帐户作为存储对象管理员添加到bucket的权限中。我尝试过各种其他角色组合(旧版阅读器/所有者、存储对象查看器等),但都没有成功
  • 正如您在函数的代码中所看到的,我专门为e