Cloud Translation创建术语表遇PERMISSION_DENIED权限错误求助
Google Cloud Translation 创建术语表权限问题解决
版本信息
"google/cloud-translate": "^1.13"
问题现状
- 查询、删除术语表功能正常执行,但创建术语表操作失败
- 错误提示:
- 错误码:7
- 错误信息:
Error: PERMISSION_DENIED. Job state: FAILED.
- 当前已配置的账号权限:
- Cloud Translation API Admin
- DataCatalog Entry Owner
- DataCatalog Glossary User
- Storage Admin
- Storage Object Viewer
- 项目此前运行正常,自7月13日起无法创建术语表
核心问题分析
从错误详情中可明确:Google Cloud Translation服务使用的官方账号cloud-ml-translation-worker@prod.google.com没有目标Cloud Storage对象的storage.objects.get访问权限,导致无法读取用于创建术语表的CSV文件(示例中为gs://trans_text/translation5823.csv)。
解决方法
方法1:为服务账号配置GCS对象读取权限
- 登录Cloud Storage控制台,找到存储桶
trans_text - 进入「权限」页面,点击「添加」按钮
- 在「新成员」输入框中填入:
cloud-ml-translation-worker@prod.google.com - 在「角色」下拉菜单中选择 Storage > Storage Object Viewer(该角色包含
storage.objects.get权限) - 点击「保存」完成配置
方法2:验证并补充权限
- 完成上述配置后重新执行创建术语表代码,若仍报错,检查IAM策略是否生效,可尝试为该账号额外添加Storage > Storage Legacy Bucket Reader角色
- 确认存储桶中的CSV对象存在,且路径与代码中
gsutil_uri一致
临时应急方案(不推荐生产环境)
若权限配置需要审批流程,可临时设置CSV对象为公共可读:
修改代码中上传文件的配置,添加predefinedAcl参数:
$bucket->upload(getCSVContents($dataContent, $language_codes), [ 'name' => $objectName, 'metadata' => ['contentType' => 'text/csv'], 'predefinedAcl' => 'publicRead' ]);
官方示例代码(中文注释调整)
use Google\ApiCore\ApiException; use Google\Cloud\Storage\StorageClient; use Google\Cloud\Translate\V3\GcsSource; use Google\Cloud\Translate\V3\Glossary; use Google\Cloud\Translate\V3\Glossary\LanguageCodesSet; use Google\Cloud\Translate\V3\GlossaryInputConfig; use Google\Cloud\Translate\V3\TranslationServiceClient; require "vendor/autoload.php"; $secret_path = "*****.json"; $projectId = "*****"; putenv("GOOGLE_APPLICATION_CREDENTIALS={$secret_path}"); $location = "us-central1"; $language_codes = ["zh-CN","en"]; $storage = new StorageClient(); $dataContent = [["六","sex"]]; $glossaryId = sprintf("translation%d",rand(1000,9999)); $objectName = $glossaryId.".csv"; try { $bucket = $storage->bucket("trans_text"); $bucket->upload(getCSVContents($dataContent, $language_codes), [ 'name' => $objectName, 'metadata' => ['contentType' => 'text/csv'] ]); $gsutil_uri = sprintf('gs://%s/%s', "trans_text", $objectName); } catch (\Exception $e) { var_dump($e->getMessage()); exit(); } function getCSVContents($data, $header) { $output = fopen('php://temp', 'w'); fputcsv($output,$header); foreach ($data as $v) { fputcsv($output, $v); } rewind($output); $contents = stream_get_contents($output); fclose($output); return $contents; } // 创建翻译服务客户端 $translationServiceClient = new TranslationServiceClient(); $formattedParent = $translationServiceClient::locationName($projectId,$location); $glossaryName = $translationServiceClient::glossaryName($projectId,$location,$glossaryId); $language_codes_set = new LanguageCodesSet(); $language_codes_set->setLanguageCodes($language_codes); $gcs_source = (new GcsSource())->setInputUri($gsutil_uri); $input_config = (new GlossaryInputConfig())->setGcsSource($gcs_source); $glossary = (new Glossary())->setName($glossaryName)->setInputConfig($input_config)->setLanguageCodesSet($language_codes_set); try { $response = $translationServiceClient->createGlossary($formattedParent, $glossary); $response->pollUntilComplete(); if ($response->operationSucceeded()) { $result = $response->getResult(); printf('操作成功,响应数据: %s' . PHP_EOL, $result->serializeToJsonString()); } else { $error = $response->getError(); printf('操作失败,错误数据: %s' . PHP_EOL, $error->serializeToJsonString()); } } catch (ApiException $ex) { printf('调用失败,错误信息: %s' . PHP_EOL, $ex->getMessage()); }
内容的提问来源于stack exchange,提问作者hongzhi wang
相关产品推荐
相关产品推荐

