Skip to content

Commit d180225

Browse files
committed
feat: api for adopted table during gen1 -> gen2 migration
1 parent 5d4b72f commit d180225

File tree

4 files changed

+104
-47
lines changed

4 files changed

+104
-47
lines changed

.changeset/tasty-wings-brush.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@aws-amplify/backend-data': minor
3+
---
4+
5+
Enabled a new "adoption" strategy for moving DynamoDB tables from Gen1 to Gen2, which will require an import operation. The migrated table will be fully managed by the Gen2 stack.

packages/backend-data/src/convert_schema.test.ts

Lines changed: 66 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ void describe('convertSchemaToCDK', () => {
8080
echo(message: String!): String!
8181
}
8282
`;
83-
const convertedDefinition = convertSchemaToCDK(
84-
graphqlSchema,
85-
secretResolver,
83+
const convertedDefinition = convertSchemaToCDK({
84+
schema: graphqlSchema,
85+
backendSecretResolver: secretResolver,
8686
stableBackendIdentifiers,
87-
);
87+
});
8888
assert.deepEqual(convertedDefinition.schema, graphqlSchema);
8989
assert.deepEqual(convertedDefinition.dataSourceStrategies, {
9090
Todo: {
@@ -107,11 +107,11 @@ void describe('convertSchemaToCDK', () => {
107107
}),
108108
})
109109
.authorization((allow) => allow.publicApiKey());
110-
const convertedDefinition = convertSchemaToCDK(
111-
typedSchema,
112-
secretResolver,
110+
const convertedDefinition = convertSchemaToCDK({
111+
schema: typedSchema,
112+
backendSecretResolver: secretResolver,
113113
stableBackendIdentifiers,
114-
);
114+
});
115115
assert.deepEqual(
116116
removeWhiteSpaceForComparison(convertedDefinition.schema),
117117
removeWhiteSpaceForComparison(expectedGraphqlSchema),
@@ -135,11 +135,11 @@ void describe('convertSchemaToCDK', () => {
135135
}),
136136
})
137137
.authorization((allow) => allow.publicApiKey());
138-
const convertedDefinition = convertSchemaToCDK(
139-
typedSchema,
140-
secretResolver,
138+
const convertedDefinition = convertSchemaToCDK({
139+
schema: typedSchema,
140+
backendSecretResolver: secretResolver,
141141
stableBackendIdentifiers,
142-
);
142+
});
143143
assert.deepEqual(convertedDefinition.dataSourceStrategies, {
144144
Todo: {
145145
dbType: 'DYNAMODB',
@@ -152,12 +152,12 @@ void describe('convertSchemaToCDK', () => {
152152
});
153153
});
154154

155-
void it('uses the only appropriate dbType and provisioningStrategy', () => {
156-
const convertedDefinition = convertSchemaToCDK(
157-
'type Todo @model @auth(rules: { allow: public }) { id: ID! }',
158-
secretResolver,
155+
void it('uses the default dbType and provisioningStrategy', () => {
156+
const convertedDefinition = convertSchemaToCDK({
157+
schema: 'type Todo @model @auth(rules: { allow: public }) { id: ID! }',
158+
backendSecretResolver: secretResolver,
159159
stableBackendIdentifiers,
160-
);
160+
});
161161
assert.equal(
162162
Object.values(convertedDefinition.dataSourceStrategies).length,
163163
1,
@@ -198,11 +198,11 @@ void describe('convertSchemaToCDK', () => {
198198
.authorization((allow) => allow.publicApiKey()),
199199
});
200200

201-
const convertedDefinition = convertSchemaToCDK(
202-
modified,
203-
secretResolver,
201+
const convertedDefinition = convertSchemaToCDK({
202+
schema: modified,
203+
backendSecretResolver: secretResolver,
204204
stableBackendIdentifiers,
205-
);
205+
});
206206

207207
assert.equal(
208208
Object.values(convertedDefinition.dataSourceStrategies).length,
@@ -253,11 +253,11 @@ void describe('convertSchemaToCDK', () => {
253253
.authorization((allow) => allow.publicApiKey()),
254254
});
255255

256-
const convertedDefinition = convertSchemaToCDK(
257-
modified,
258-
secretResolver,
256+
const convertedDefinition = convertSchemaToCDK({
257+
schema: modified,
258+
backendSecretResolver: secretResolver,
259259
stableBackendIdentifiers,
260-
);
260+
});
261261

262262
assert.equal(
263263
Object.values(convertedDefinition.dataSourceStrategies).length,
@@ -337,11 +337,11 @@ void describe('convertSchemaToCDK', () => {
337337
.authorization((allow) => allow.publicApiKey()),
338338
});
339339

340-
const convertedDefinition = convertSchemaToCDK(
341-
modified,
342-
secretResolver,
340+
const convertedDefinition = convertSchemaToCDK({
341+
schema: modified,
342+
backendSecretResolver: secretResolver,
343343
stableBackendIdentifiers,
344-
);
344+
});
345345

346346
assert.equal(
347347
Object.values(convertedDefinition.dataSourceStrategies).length,
@@ -420,11 +420,11 @@ void describe('convertSchemaToCDK', () => {
420420
.authorization((allow) => allow.publicApiKey()),
421421
});
422422

423-
const convertedDefinition = convertSchemaToCDK(
424-
modified,
425-
secretResolver,
423+
const convertedDefinition = convertSchemaToCDK({
424+
schema: modified,
425+
backendSecretResolver: secretResolver,
426426
stableBackendIdentifiers,
427-
);
427+
});
428428

429429
assert.equal(
430430
Object.values(convertedDefinition.dataSourceStrategies).length,
@@ -480,11 +480,11 @@ void describe('convertSchemaToCDK', () => {
480480
.authorization((allow) => allow.publicApiKey()),
481481
});
482482

483-
const convertedDefinition = convertSchemaToCDK(
484-
modified,
485-
secretResolver,
483+
const convertedDefinition = convertSchemaToCDK({
484+
schema: modified,
485+
backendSecretResolver: secretResolver,
486486
stableBackendIdentifiers,
487-
);
487+
});
488488

489489
assert.equal(
490490
Object.values(convertedDefinition.dataSourceStrategies).length,
@@ -514,4 +514,33 @@ void describe('convertSchemaToCDK', () => {
514514
},
515515
);
516516
});
517+
518+
void it('produces IMPORTED strategy for importedTableName', () => {
519+
const result = convertSchemaToCDK({
520+
schema: 'type Todo @model { id: ID! }',
521+
backendSecretResolver: secretResolver,
522+
stableBackendIdentifiers,
523+
importedTableName: 'ExistingTable',
524+
});
525+
assert.deepEqual(Object.values(result.dataSourceStrategies)[0], {
526+
dbType: 'DYNAMODB',
527+
provisionStrategy: 'IMPORTED_AMPLIFY_TABLE',
528+
tableName: 'ExistingTable',
529+
});
530+
});
531+
532+
void it('produces ADOPTED strategy for shouldAdoptExistingTable', () => {
533+
const result = convertSchemaToCDK({
534+
schema: 'type Todo @model { id: ID! }',
535+
backendSecretResolver: secretResolver,
536+
stableBackendIdentifiers,
537+
importedTableName: 'AdoptedTable',
538+
shouldAdoptExistingTable: true,
539+
});
540+
assert.deepEqual(Object.values(result.dataSourceStrategies)[0], {
541+
dbType: 'DYNAMODB',
542+
provisionStrategy: 'ADOPTED_AMPLIFY_TABLE',
543+
tableName: 'AdoptedTable',
544+
});
545+
});
517546
});

packages/backend-data/src/convert_schema.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ const IMPORTED_DYNAMO_DATA_SOURCE_STRATEGY = {
7272
provisionStrategy: 'IMPORTED_AMPLIFY_TABLE',
7373
} as const;
7474

75+
// Adopted strategy where Amplify will synthesize a managed CFN table resource
76+
const ADOPTED_DYNAMO_DATA_SOURCE_STRATEGY = {
77+
dbType: 'DYNAMODB',
78+
provisionStrategy: 'ADOPTED_AMPLIFY_TABLE',
79+
} as const;
80+
7581
// Translate the external engine types to the config values
7682
// Reference: https://github.com/aws-amplify/amplify-category-api/blob/fd7f6fbc17c199331c4b04debaff69ea0424cd74/packages/amplify-graphql-api-construct/src/model-datasource-strategy-types.ts#L25
7783
const SQL_DB_TYPES = {
@@ -81,18 +87,28 @@ const SQL_DB_TYPES = {
8187

8288
/**
8389
* Given an input schema type, produce the relevant CDK Graphql Def interface
84-
* @param schema TS schema builder definition or string GraphQL schema
85-
* @param backendSecretResolver secret resolver
86-
* @param stableBackendIdentifiers backend identifiers
87-
* @param importedTableName table name to use for imported models. If not defined the model is not imported.
90+
* @param params configuration parameters
91+
* @param params.schema TS schema builder definition or string GraphQL schema
92+
* @param params.backendSecretResolver secret resolver
93+
* @param params.stableBackendIdentifiers backend identifiers
94+
* @param params.importedTableName table name to use for imported models. If not defined the model is not imported.
95+
* @param params.shouldAdoptExistingTable whether to adopt the existing table
8896
* @returns the cdk graphql definition interface
8997
*/
90-
export const convertSchemaToCDK = (
91-
schema: DataSchema,
92-
backendSecretResolver: BackendSecretResolver,
93-
stableBackendIdentifiers: StableBackendIdentifiers,
94-
importedTableName?: string,
95-
): IAmplifyDataDefinition => {
98+
export const convertSchemaToCDK = (params: {
99+
schema: DataSchema;
100+
backendSecretResolver: BackendSecretResolver;
101+
stableBackendIdentifiers: StableBackendIdentifiers;
102+
importedTableName?: string;
103+
shouldAdoptExistingTable?: boolean;
104+
}): IAmplifyDataDefinition => {
105+
const {
106+
schema,
107+
backendSecretResolver,
108+
stableBackendIdentifiers,
109+
importedTableName,
110+
shouldAdoptExistingTable,
111+
} = params;
96112
if (isDataSchema(schema)) {
97113
/**
98114
* This is not super obvious, but the IAmplifyDataDefinition interface requires a record of each model type to a
@@ -146,6 +162,12 @@ export const convertSchemaToCDK = (
146162
}
147163

148164
if (importedTableName) {
165+
if (shouldAdoptExistingTable) {
166+
return AmplifyDataDefinition.fromString(schema, {
167+
...ADOPTED_DYNAMO_DATA_SOURCE_STRATEGY,
168+
tableName: importedTableName,
169+
} as unknown as ModelDataSourceStrategy);
170+
}
149171
return AmplifyDataDefinition.fromString(schema, {
150172
...IMPORTED_DYNAMO_DATA_SOURCE_STRATEGY,
151173
tableName: importedTableName,

packages/backend-data/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,4 +253,5 @@ export type DataLogLevel = Extract<
253253
export type AmplifyGen1DynamoDbTableMapping = {
254254
branchName: string;
255255
modelNameToTableNameMapping?: Record<string, string>;
256+
shouldAdoptExistingTable?: boolean;
256257
};

0 commit comments

Comments
 (0)