amplify-codegen
amplify-codegen copied to clipboard
Amplify codegen models is creating id when primarykey is specified
Before opening, please confirm:
- [X] I have installed the latest version of the Amplify CLI (see above), and confirmed that the issue still persists.
- [X] I have searched for duplicate or closed issues.
- [X] I have read the guide for submitting bug reports.
- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
- [X] I have removed any sensitive information from my code snippets and submission.
How did you install the Amplify CLI?
npm
If applicable, what version of Node.js are you using?
v16.14.0
Amplify CLI Version
8.0.3
What operating system are you using?
Mac
Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.
No
Amplify Categories
api
Amplify Commands
codegen
Describe the bug
When specifying the following model.
type Todo @model {
key: ID! @primaryKey
name: String!
description: String
}
I'm still getting an id field in the files created by amplify codegen models
Expected behavior
I expect the DataStore to adhere to the primaryKey directive.
Reproduction steps
Create a schema as described and then do amplify codegen models
GraphQL schema(s)
type Todo @model {
key: ID! @primaryKey
name: String!
description: String
}
Log output
# Put your logs below this line
Additional information
schema.js
export const schema = {
"models": {
"Todo": {
"name": "Todo",
"fields": {
"id": {
"name": "id",
"isArray": false,
"type": "ID",
"isRequired": true,
"attributes": []
},
"key": {
"name": "key",
"isArray": false,
"type": "ID",
"isRequired": true,
"attributes": []
},
"name": {
"name": "name",
"isArray": false,
"type": "String",
"isRequired": true,
"attributes": []
},
"description": {
"name": "description",
"isArray": false,
"type": "String",
"isRequired": false,
"attributes": []
},
"createdAt": {
"name": "createdAt",
"isArray": false,
"type": "AWSDateTime",
"isRequired": false,
"attributes": [],
"isReadOnly": true
},
"updatedAt": {
"name": "updatedAt",
"isArray": false,
"type": "AWSDateTime",
"isRequired": false,
"attributes": [],
"isReadOnly": true
}
},
"syncable": true,
"pluralName": "Todos",
"attributes": [
{
"type": "model",
"properties": {}
},
{
"type": "key",
"properties": {
"fields": [
"key"
]
}
}
]
}
},
"enums": {},
"nonModels": {},
"version": "fe2b4ee8f0b0a06f4de46e98893aaf50"
};
Additionally it looks like when using the Datastore the subscriptions are looking for the id column which doesn't exist on the server.
Hey @kddejong :wave: thanks for raising this! I was able to successfully reproduce this behavior using the provided steps:
type Todo @model {
key: ID! @primaryKey
name: String!
description: String
}
outputs (in our API's build/
directory):
type Todo {
key: ID!
name: String!
description: String
createdAt: AWSDateTime!
updatedAt: AWSDateTime!
}
However the generated models include a required id
field as you mentioned:
export declare class Todo {
readonly id: string;
readonly key: string;
readonly name: string;
readonly description?: string | null;
readonly createdAt?: string | null;
readonly updatedAt?: string | null;
constructor(init: ModelInit<Todo, TodoMetaData>);
static copyOf(source: Todo, mutator: (draft: MutableModel<Todo, TodoMetaData>) => MutableModel<Todo, TodoMetaData> | void): Todo;
}
Marking as a codegen bug 🙂
Hi @kddejong, this is a known gap in DataStore interacting with a customer Primary Key today. If you refer to the Javascript DataStore docs https://docs.amplify.aws/lib/datastore/relational/q/platform/js/ we do call out that you'll need to explicitly set the id
column as well. We are actively working on resolving this feature parity issue, and will be releasing support in the future.
Hey @kddejong I ran into the same issue and saw your comment. But I ran into another issue is that I cannot override the id column with @primaryKey when creating new item. It seems like amplify is ignoring the @primaryKey notation.
Hi @kddejong, @shrentseng, the team has just merged in support for custom primary keys into the JS library, the next release of the aws-amplify
library should add support for custom primary keys, resolving the issues you're seeing here. We are not enabling this functionality for all projects right now, but leaving it behind a feature flag you can enable in the /amplify/cli.json
file, called respectPrimaryKeyAttributesOnConnectionField. In order to take advantage of this, once you've upgraded to aws-amplify
>4.3.37 (not yet released), you can enable this functionality by flipping that flag to true.
Note: If you use Amplify Studio for CMS or Data Modeling functionality, I'd recommend against enabling that flag for now, as it will cause render issues in Studio. We are working through those issues, and will enable this functionality by default once resolved.
@alharris-at Could you please clarify if the bug can be somehow resolved with regard to Amplify for iOS? Looks like it is became a major issue for iOS:
Amplify/ModelSchema.swift:104: Fatal error: Primary Key not defined for `Boat`
2022-12-09 17:11:23.082976+0200 AddBoat[825:70376] Amplify/ModelSchema.swift:104: Fatal error: Primary Key not defined for `Boat`
while my model is described as in schema.graphql file:
type Boat @model @auth(rules: [
{ allow: owner } ]) {
id: ID! @primaryKey
...
I'm getting the same issue - I am using a custom primary key name and an id field is still being added.
userID : ID! @primaryKey
my "respectprimarykeyattributesonconnectionfield": true, was already set by default. I'm using version "@aws-amplify/core" "5.0.16"
Just hit this issue in our Swift project. Manually removed the offending id fields in the generated code and switched to specifying a primaryKey(fields:) in model.attributes.
I'm also running into this for my typescript/react project. If I leave the field name as id
in the model, then it does work as expected (even when "id" is annotated as @primaryKey). But as soon as I change the name of the @primaryKey field, it stops working.
The behavior that I see is that the Mutationcreate<ENTITY>init0Function
pipeline resolver is still generates $util.qr($ctx.stash.defaultValues.put("id", $util.autoId()))
instead of using the custom field name there. This value gets merged into the defaults and when the entity eventually gets created in Dynamo, it has this id field and default value merged into the final object. More importantly though, the actual @primaryKey field is not getting an auto-generated value. Furthermore, the GraphQL schema has the @primaryKey field marked as required on create, instead of allowing the field to be optional and populated with a default value in the resolver. I can confirm that when the @primaryKey is id
, the createMutation input has it as optional and it does get auto-populated in the resolver. So it seems like the code generation just isn't taking the primaryKey field into account when generating the resolvers and GraphQL schema (though the actual dynamoDB table does have the custom field as the primary key).
For some context, here is the change I have in my schema.graphql:
type Zone @model {
- id: String! @primaryKey
+ zoneId: String! @primaryKey
title: String!
and you can see from my schema.json that the id field is now required for the create input:
{
"kind" : "INPUT_OBJECT",
"name" : "CreateZoneInput",
"description" : null,
"fields" : null,
"inputFields" : [ {
- "name" : "id",
+ "name" : "zoneId",
"description" : null,
"type" : {
+ "kind" : "NON_NULL",
+ "name" : null,
+ "ofType" : {
"kind" : "SCALAR",
"name" : "String",
"ofType" : null
+ }
},
"defaultValue" : null
},
It would be great if this can be fixed before I need to push to production (since the primaryKey fieldname change requires drop/replace on the whole table), but for now I'm going to limp along with the default "id" field name.