这是我的代码:
// vim:ft=javascript:
const {Spanner} = require('@google-cloud/spanner');
const spanner = new Spanner({projectId: 'gcp-in-action-317405'});
const instance = spanner.instance('test-instance');
const database = instance.database('test-database');
const employees = database.table('employees');
employees.insert([
{employee_id: 1, name: 'Steve Jobs', start_date: '1976-04-01'},
{employee_id: 2, name: 'Bill Gates', start_date: '1975-04-04'},
{employee_id: 3, name: 'Larry Page', start_date: '1976-04-01'}
]).then((date) => {
console.log('Saved data!', data);
});
代码运行后退出,并出现以下错误:
(node:24310) UnhandledPromiseRejectionWarning: Error: 7 PERMISSION_DENIED: Cloud Spanner API has not been used in project 84555343487 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/spanner.googleapis.com/overview?project=84555343487 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
at Object.callErrorFromStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client.js:179:52)
at listener.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:80:35)
at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/grpc-gcp/build/src/index.js:73:29)
at InterceptingListenerImpl.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:75:23)
at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141)
at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)
at process.nextTick (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:145:78)
at process._tickCallback (internal/process/next_tick.js:61:11)
(node:24310) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:24310) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:24310) UnhandledPromiseRejectionWarning: Error: 7 PERMISSION_DENIED: Cloud Spanner API has not been used in project 84555343487 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/spanner.googleapis.com/overview?project=84555343487 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
at Object.callErrorFromStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client.js:179:52)
at listener.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:80:35)
at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/grpc-gcp/build/src/index.js:73:29)
at InterceptingListenerImpl.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:75:23)
at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141)
at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)
at process.nextTick (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:145:78)
at process._tickCallback (internal/process/next_tick.js:61:11)
(node:24310) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
对于进一步的上下文,这里是gcloud projects list
:的输出
PROJECT_ID NAME PROJECT_NUMBER
gcp-in-action-317405 GCP in Action 827217411854
qibla-finder-1507320565537 Qibla Finder 84555343487
显然,我想与";GCP在行动";(827217411854(,但谷歌云认为我正在处理";Qibla Finder"(84555343487(,我已经好几年没有用它开发了。在任何人提出要求之前,我已经确定运行gcloud config set project gcp-in-action-317405
。如何将扳手指向正确的方向?
您似乎正在使用应用程序默认凭据(GOOGLE_APPLICATION_CREDENTIALS=/path/to/some.key
(对代码进行身份验证。
我怀疑您正在使用的密钥属于qibla-finder-1507320565537
所拥有的服务帐户,并且当您的代码进行调用时,正在检查拥有该帐户的项目是否有API(但它没有在其中启用(。
您可能想在gcp-in-action-317405
中创建一个新的服务帐户,为其指定合适的Spanner等角色,并使用它验证您的代码。
注意您可以在其他项目中授予现有服务帐户对Spanner的访问权限,但您仍需要在
qibla-finder-1507320565537
中启用API
更新:如何创建服务帐户
使用gcloud
,您可以创建一个服务帐户,授予它一个合适的角色,创建一个密钥,并使用导出密钥
PROJECT=gcp-in-action-317405
ACCOUNT=spanner-user
EMAIL=${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com
# Create Service Account
gcloud iam service-accounts create ${ACCOUNT}
--display-name="Spanner User"
--description="Used by code to interact with Spanner"
--project=${PROJECT}
# Grant Service Account Database User role
# https://cloud.google.com/spanner/docs/iam#roles
gcloud projects add-iam-policy-binding ${PROJECT}
--member=serviceAccount:${EMAIL}
--role=roles/spanner.databaseUser
# Generate a key for this Service Account
gcloud iam service-accounts keys create ${PWD}/${ACCOUNT}.json
--iam-account=${EMAIL}
--project=${PROJECT}
# Use Application Default Credentials
export GOOGLE_APPLICATION_CREDENTIALS=${PWD}/${ACCOUNT}.json
# Run your code