Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: generate ts schema from pg serial field #2952

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

p5quared
Copy link
Member

@p5quared p5quared commented Oct 14, 2024

Description of changes

Update TS schema generator to properly annotate serial fields from Postgres datasources.

e.g.:
myField SERIAL -> myField: a.integer().default()

Explanation:
We already populate field.default when importing a DB schema, but don't really do anything with it prior to this change.

Now, we check if the field default is DB_GENERATED, and the value for the generated field indicates it is a SERIAL column. If this is the case, we annotate the TS schema field with .default().

CDK / CloudFormation Parameters Changed

N/A

Issue #, if available

N/A

Description of how you validated changes

See test cases in

  • packages/amplify-graphql-schema-generator/src/__tests__/generate-ts-data-schema.test.ts
  • packages/amplify-graphql-schema-generator/src/__tests__/pg-string-datasource-adapter.test.ts

Checklist

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@p5quared p5quared force-pushed the feat/serial-schema-generation branch 2 times, most recently from 8d4f420 to f411e70 Compare October 14, 2024 22:48
@@ -145,6 +145,19 @@ type Story @refersTo(name: \\"stories\\") @model {
"
`;

exports[`generate graphqlSchemaFromSQLSchema creates graphql schema from "postgres" "serial" schema 1`] = `
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This snapshot is not intentional as we are not intending to support GQL generation here. It is generated automatically to test against anyway from the schemas in __utils__.

@@ -249,6 +249,108 @@ describe('Type name conversions', () => {
expect(graphqlSchema).toMatchSnapshot();
});

it.each([
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These cases are not exhaustive over every Field that could exist but cover the most unique cases.

@p5quared p5quared force-pushed the feat/serial-schema-generation branch from f411e70 to 09e08e8 Compare October 14, 2024 23:03
@p5quared p5quared force-pushed the feat/serial-schema-generation branch from 09e08e8 to b793733 Compare October 14, 2024 23:03
const createDataType = (type: FieldType): ts.Node => {
if (type.kind === 'Scalar') {
const createDataType = (field: Field): ts.Node => {
const sequenceRegex = /^nextval\(.+::regclass\)$/;
Copy link
Member Author

@p5quared p5quared Oct 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regex Explain

I went back and forth on a few approaches to this check but I eventually felt that a quick regex is the simplest surefire way to identify SERIAL fields. In the future I think this logic could be extracted into something like if (canLetDBGenerate(field)) which evaluates rules isSerial(field) || isUserDefinedFunction(field) etc... But I felt that might be premature for this implementation.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For more context, here's what a value for column_default looks like on a serial field when we query the DB schema:
nextval('serial_table_number_seq'::regclass).

@p5quared p5quared marked this pull request as ready for review October 14, 2024 23:20
@p5quared p5quared requested review from a team as code owners October 14, 2024 23:20
@p5quared p5quared changed the title Feat/serial schema generation feat: generate ts schema from pg serial field Oct 14, 2024
Comment on lines +262 to +265
\\"CoffeeQueue\\": a.model({
id: a.integer().default(),
name: a.string(),
orderNumber: a.integer().default()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the desired behavior of this PR.

@@ -279,3 +279,38 @@ Array [
},
]
`;

exports[`testPostgresStringDataSourceAdapter sets the model field correctly from a schema with a SERIAL field 1`] = `
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behavior is not new but I am codifying it since generation depends on it now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant