I'm trying to find the table name to use the dynamo db that is auto generated using AWS Amplify after creating a schema using 'data'. How can I find that?
Here is what I've tried:
resource.ts file
const schema = a
.schema({
UserProfileFlags: a.customType({
isBetaUser: a.boolean(),
isFounder: a.boolean(),
isBanned: a.boolean(),
isSuspended: a.boolean(),
isVerified: a.boolean(),
isDeleted: a.boolean(),
}),
UserProfile: a
.model({
userName: a.string().required(),
owner: a
.string()
.authorization((allow) => [allow.owner().to(['read', 'delete'])]),
...
to define a database in dynamo named UserProfile. That works fine, the db is created and the table exists. Now I'm trying to create a function to access that table. I've tried many iterations, but they all have errors/won't compile or work:
I found this:
import { DynamoDB } from 'aws-sdk';
import { getDataSource } from '@aws-amplify/backend-function';
import type { Schema } from '../../data/resource';
const dynamodb = new DynamoDB.DocumentClient();
export const handler: Schema['createEmptyProfile']['handler'] = async (event, context) => {
const dataSource = getDataSource(context);
const TABLE_NAME = dataSource.resources.UserProfile.tableName;
This one tells me that import { getDataSource } from '@aws-amplify/backend-function';
is a problem:
Module '"@aws-amplify/backend-function"' has no exported member 'getDataSource'.ts(2305)
I've also tried running this: npx ampx generate graphql-client-code --out /graphql
and then
import { env } from "$amplify/env/post-confirmation";
...
endpoint: env.AMPLIFY_DATA_GRAPHQL_ENDPOINT,
...
But this too shows AMPLIFY_DATA_GRAPHQL_ENDPOINT is undefined, and if I look in the generated .ts files, I don't see it either.
That kind of makes sense, since I'm not sure how that would work when deployed, as it needs a different table name. This is all running against a local sandbox.
Here is the docs link that I can find: https://docs.amplify.aws/react/build-a-backend/functions/examples/create-user-profile-record/
I'm running Amplify Gen 2 also; here's what worked for me.
I wasn't able to get any solution involving setting environment variables to work reliably. But what did work was to create SSM parameters with the values I needed, and grant my lambda permissions to read them.
In my backend, after creating the resources I need (AccountTable's ARN, in this case):
const envName = process.env.AMPLIFY_BRANCH || 'dev';
const accountTableParam = new cdk.aws_ssm.StringParameter(
apiStack,
"AccountTableParam",
{
parameterName: `/secure-site/${envName}/account-table-name`,
stringValue: accountTable.tableName,
}
);
const allowSignLambdaToAccessAccountTablePolicy = new Policy(
cdk.Stack.of(accountTable),
"allowSignLambdaToAccessAccountTablePolicy",
{
statements: [
new PolicyStatement({
effect: Effect.ALLOW,
actions: [
"dynamodb:GetItem",
"dynamodb:UpdateItem",
"dynamodb:Query",
"dynamodb:Scan",
],
resources: [accountTable.tableArn],
}),
new PolicyStatement({
effect: Effect.ALLOW,
actions: ["ssm:GetParameter"],
resources: [
accountTableParam.parameterArn,
],
}),
],
}
);
Then in my lambda's code, I could read the parameter:
const ssmClient = new SSMClient();
const envName = process.env.AMPLIFY_BRANCH || 'dev';
async function getParameter(name: string): Promise<string> {
const paramPath = `/secure-site/${envName}/${name}`;
const command = new GetParameterCommand({ Name: paramPath });
const response = await ssmClient.send(command);
return response.Parameter?.Value || '';
}
const table = await getParameter('account-table-name');