英文:
How to reuse dynamoDB table
问题
I use aws cdk to deploy a stack that contains a dynamoDB table. For each deploy of my stack, CloudFormation creates a new table and links it to my lambda function. I want to know how I can reuse an existing table, without the need to create a new one if it was already created for this stack (to avoid migrating my record to a new instance of the dynamoDB table).
Here is my code:
const table = new Table(stack, id, {
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
removalPolicy: RemovalPolicy.SNAPSHOT,
});
I previously tried to use Table.fromTableName
, but I couldn't link my lambda function to the table...
Here is the code I tried:
let myTable: Table; // my table
let lambdaFunction: Function = new Function(...); // my function
// table creation
try {
myTable = Table.fromTableName(stack, tableId, name);
} catch (_) {
myTable = new Table(stack, id, {
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
removalPolicy: RemovalPolicy.SNAPSHOT,
});
}
// referencing the table in my lambda function via env
lambdaFunction.addEnvironment("TABLE_NAME", myTable.tableName);
When the lambda tries to access the table a ResourceNotFound
exception is thrown.
Any ideas?
As well I heard that if I use the same tableName
in new Table(...)
dynamoDB will return me the existing table without creating a new one, but I don't know if it's true... Does someone knows?
英文:
I use aws cdk to deploy a stack that contains a dynamoDB table. For each deploy of my stack, CloudFormation creates a new table and links it to my lambda function. I want to know how I can reuse an existing table, without the need to create a new one if it was already created for this stack (to avoid migrating my record to a new instance of the dynamoDB table).
Here is my code:
const table = new Table(stack, id, {
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
removalPolicy: RemovalPolicy.SNAPSHOT,
});
I previously tried to use Table.fromTableName
, but I cloudn't link my lambda function to the table...
Here is the code I tried:
let myTable: Table; // my table
let lambdaFunction: Function = new Function(...); // my function
// table creation
try {
myTable = Table.fromTableName(stack, tableId, name);
} catch (_) {
myTable = new Table(stack, id, {
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
removalPolicy: RemovalPolicy.SNAPSHOT,
});
}
//referencing the table in my lambda function via env
lambdaFunction.addEnvironment("TABLE_NAME", myTable.tableName);
When the lambda tries to access the table a ResourceNotFound
exception is thrown.
Any ideas?
As well I heard that if I use the same tableName
in new Table(...)
dynamoDB will return me the existing table without creating a new one, but I don't know if it's true...
Does someone knows?
答案1
得分: 0
首先,您需要更改表的保留策略,因为Snapshot
不会以可用的方式保留您的表和数据。明确定义表名还将使您能够轻松地重新导入表,而无需理解 CDK 为您命名的表名。
removalPolicy: RemovalPolicy.RETAIN,
tableName: 'MyLovelyTable',
然后,只要您提供来自Table
接口的正确表名,Table.fromTableName
就可以正常工作。
const importedTable = dynamodb.Table.fromTableName(
this,
'table-from-name-id',
'MyLovelyTable',
);
如果您经常创建堆栈,并且不经常知道表名是什么,那么每次更改表时,您可以将表名存储在Parameter Store中,并在需要时检索它。
英文:
First of all you need to change retention policy of the table, as a Snapshot
will not retain your table and data in a usable manner. Explicitly defining a table name will also allow you to easily import the table again, without having to understand what CDK named the table for you.
removalPolicy: RemovalPolicy.RETAIN,
tableName: 'MyLovelyTable',
Then Table.fromTableName
will work, as long as you provide the correct table name from the Table
interface.
const importedTable = dynamodb.Table.fromTableName(
this,
'table-from-name-id',
'MyLovelyTable',
);
If you create the stack often, and don't often know what the tableName is, then every time you change the table you can store the name in Parameter Store and retrieve it when needed.
答案2
得分: 0
以下是您要翻译的内容:
我重新检查了这个问题,实际答案是要使用常量构造函数 ID 以及常量资源名称。
从这篇博客中获取信息:
> 但正如我们之前讨论过的,首先替换资源可能并不是最好的做法。所以为了防止这种情况发生,我们只需要不修改 CDK 构造的 ID。
所以我所做的是提供硬编码的构造函数 ID,以及硬编码的表名,这些都不会改变。这样可以保留资源的逻辑 ID,CloudFormation 可以识别它,防止删除和重新创建资源。
请注意,如果您使用嵌套构造函数,则需要采用不同的方法,详见博客:
> CDK 根据完整的构造函数“路径”生成逻辑 ID。对于嵌套构造函数,所有“更高级”的构造函数的 ID 用于创建唯一的逻辑 ID。即使我们不更改构造函数的 ID,将构造函数移到其他构造函数中也会更改生成的逻辑 ID。这在开发或重构过程中经常发生。
所以,如下所示是修复后的代码:
myTable = new Table(stack, "MyTableConstructor", {
tableName: "MyTable",
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
removalPolicy: RemovalPolicy.SNAPSHOT,
});
这将适用于现有的表,无需使用 Table.fromTableName
进行导入
因此,问题不是与表的删除策略或使用 Table.fromTableName
有关,而是逻辑 ID 出现问题...
英文:
I rechecked the matter, the answer actually is to use constant constructor ids along with constant resource names.
From this blog:
>But as we discussed earlier, replacing resources is likely not the best thing to do in the first place. So to prevent it, we just don’t modify the CDK Construct IDs.
So what I did is to give hard-coded constructor ids, along with hard-coded table name, that wouldn't be changed. This preserve the logical ID of the resource to CloudFormation would identify it and prevent deletion and re-creation of the resource.
Note that you need to take a different approach if you are using nested constructors, as detailed in the blog:
>CDK generates the Logical IDs based on the full Construct “path”. With nested Constructs, IDs of all “higher” Constructs are used to create the unique Logical ID. [...] So even if we don’t change the Construct IDs, moving Constructs into other Constructs changes generated Logical IDs. This is what often happens during development or refactoring.
So, as said here is the fixed code:
myTable = new Table(stack, "MyTableConstructor", {
tableName: "MyTable",
billingMode: BillingMode.PAY_PER_REQUEST,
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
removalPolicy: RemovalPolicy.SNAPSHOT,
});
This will work with an existing table, no need to use Table.fromTableName
to import it
So, it wasn't linked to the removal policy of the table or the use of Table.fromTableName
, only that the logical ID was messed up...
答案3
得分: -1
为了在TypeScript中重用DynamoDB表,您可以使用AWS JavaScript/TypeScript SDK(aws-sdk
包)与DynamoDB进行交互。以下是如何重用DynamoDB表的示例:
-
在您的项目目录中运行以下命令安装必要的依赖项:
npm install aws-sdk
-
在您的TypeScript文件中导入必要的模块:
import AWS from 'aws-sdk';
-
使用您的AWS凭据和适当的区域配置AWS SDK:
AWS.config.update({ region: 'YOUR_REGION', accessKeyId: 'YOUR_ACCESS_KEY', secretAccessKey: 'YOUR_SECRET_ACCESS_KEY', });
用您实际的AWS区域和凭据替换
'YOUR_REGION'
、'YOUR_ACCESS_KEY'
和'YOUR_SECRET_ACCESS_KEY'
。 -
使用配置的AWS SDK创建一个DynamoDB文档客户端:
const dynamodb = new AWS.DynamoDB.DocumentClient();
-
使用DynamoDB客户端对现有表执行操作。例如,要从表中检索项目:
const params = { TableName: 'YOUR_TABLE_NAME', Key: { // 指定主键属性 primaryKey: 'PRIMARY_KEY_VALUE', }, }; dynamodb.get(params, (error, data) => { if (error) { console.error('Error retrieving item:', error); } else { console.log('Retrieved item:', data.Item); } });
用您现有的DynamoDB表的名称替换
'YOUR_TABLE_NAME'
,并用您要检索的主键属性的实际值替换'PRIMARY_KEY_VALUE'
。
通过按照这些步骤操作,您可以重用现有的DynamoDB表并使用AWS JavaScript/TypeScript SDK执行各种操作。
英文:
To reuse a DynamoDB table in TypeScript, you can use the AWS SDK for JavaScript/TypeScript (aws-sdk
package) to interact with DynamoDB. Here's an example of how you can reuse a DynamoDB table:
-
Install the necessary dependencies by running the following command in your project directory:
npm install aws-sdk
-
Import the necessary modules in your TypeScript file:
import AWS from 'aws-sdk';
-
Configure the AWS SDK with your AWS credentials and the appropriate region:
AWS.config.update({ region: 'YOUR_REGION', accessKeyId: 'YOUR_ACCESS_KEY', secretAccessKey: 'YOUR_SECRET_ACCESS_KEY', });
Replace 'YOUR_REGION', 'YOUR_ACCESS_KEY', and 'YOUR_SECRET_ACCESS_KEY' with your actual AWS region and credentials.
-
Create a DynamoDB document client using the configured AWS SDK:
const dynamodb = new AWS.DynamoDB.DocumentClient();
-
Use the DynamoDB client to perform operations on the existing table. For example, to retrieve an item from the table:
const params = { TableName: 'YOUR_TABLE_NAME', Key: { // Specify the primary key attributes primaryKey: 'PRIMARY_KEY_VALUE', }, }; dynamodb.get(params, (error, data) => { if (error) { console.error('Error retrieving item:', error); } else { console.log('Retrieved item:', data.Item); } });
Replace 'YOUR_TABLE_NAME' with the name of your existing DynamoDB table and 'PRIMARY_KEY_VALUE' with the actual value of the primary key attribute you want to retrieve.
By following these steps, you can reuse the existing DynamoDB table and perform various operations using the AWS SDK for JavaScript/TypeScript.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论