amplify-codegen
amplify-codegen copied to clipboard
codegen models doesn't generate id for belongs-to connection
Before opening, please confirm:
I have searched for duplicate or closed issues. I have read the guide for submitting bug reports. I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
JavaScript Framework
React
Amplify APIs
GraphQL API, DataStore
Amplify Categories
api
Environment information
# Put output below this line
System:
OS: macOS 11.2.3
CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
Memory: 452.77 MB / 32.00 GB
Shell: 3.2.1 - /usr/local/bin/fish
Binaries:
Node: 12.18.3 - ~/n/bin/node
Yarn: 1.22.10 - ~/npm/bin/yarn
npm: 7.5.2 - ~/npm/bin/npm
Browsers:
Chrome: 89.0.4389.114
Firefox: 87.0
Safari: 14.0.3
npmGlobalPackages:
@aws-amplify/cli: 4.46.1
@marlonmarcello/vite-plugin-pug: 1.0.3
@wethegit/preact-stickerbook: 1.0.2
@wethegit/sweet-potato-components: 0.0.3
@wethegit/sweet-potato-cooker: 0.9.0
@wethegit/sweet-potato-peeler: 0.3.8
node-gyp: 7.1.2
npm: 7.5.2
twosg: 0.1.0
tpci-tcgportal: 1.0.0
yarn: 1.22.10
Describe the bug
By following the tutorial on the docs on how to create a belongs-to connection I came up with the following graphql.schema:
type Project @model {
id: ID!
name: String!
emails: [Email] @connection(keyName: "byProject", fields: ["id"])
}
type Email @model @key(name: "byProject", fields: ["projectID"]) {
id: ID!
title: String!
language: String!
body: String!
projectID: ID!
project: Project @connection(fields: ["projectID"])
}
After that, I ran amplify codegen
and amplify codegen models
.
The generated model was the following:
import { ModelInit, MutableModel, PersistentModelConstructor } from "@aws-amplify/datastore";
export declare class Project {
readonly id: string;
readonly name: string;
readonly emails?: (Email | null)[];
constructor(init: ModelInit<Project>);
static copyOf(source: Project, mutator: (draft: MutableModel<Project>) => MutableModel<Project> | void): Project;
}
export declare class Email {
readonly id: string;
readonly title: string;
readonly language: string;
readonly body: string;
readonly project?: Project;
constructor(init: ModelInit<Email>);
static copyOf(source: Email, mutator: (draft: MutableModel<Email>) => MutableModel<Email> | void): Email;
}
Issue 1:
Notice that the Email
class is missing projectID
.
Issue 2:
Because of Issue 1, when using typescript the following error is given:
const email = await DataStore.save(
new Email({
title: "Email title",
language: "en",
body: JSON.stringify(rows),
projectID: id,
})
);
// Argument of type '{ title: string; language: string; body: string; projectID: string; }' is not assignable to parameter of type 'ModelInit<Email>'.
// Object literal may only specify known properties, but 'projectID' does not exist in type 'ModelInit<Email>'. Did you mean to write 'project'?ts(2345)
Expected behavior
amplify codegen models
should include the projectID
field on the generated class.
Reproduction steps
-
amplify init
-
amplify add api
- Select GraphQL and go through base steps
- Use the schema provided above
-
amplify codegen models
Notice the missing connection ID.
Code Snippet
// Put your code below this line.
Log output
// Put your logs below this line
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Hi @marlonmarcello. Thanks for reporting this. We will look into this soon and let you know.
Hi @marlonmarcello, can you try to pass in the Project
object to associate with the Email like,
const email = await DataStore.save(
new Email({
title: "Email title",
language: "en",
body: JSON.stringify(rows),
project: project,
})
);
Hi @marlonmarcello, can you try to pass in the
Project
object to associate with the Email like,const email = await DataStore.save( new Email({ title: "Email title", language: "en", body: JSON.stringify(rows), project: project, }) );
This is not an issue with passing in data, it's an issue with generating the correct types.
We have the same exact issue, where not only certain properties are removed in the TS definitions, but also id
is added when it doesn't exist.
Example:
type OrderAssignment
@model
@key(fields: [ "orderId", "designWorkflowStageId" ])
{
businessId: ID!
orderId: ID!
order: Order @connection(fields: [ "orderId" ])
designWorkflowStageId: ID!
status: OrderAssignmentStatusType!
}
results in:
export declare class OrderAssignment {
readonly id: string;
readonly businessId: string;
readonly order?: Order;
readonly designWorkflowStageId: string;
readonly status: OrderAssignmentStatusType | keyof typeof OrderAssignmentStatusType;
constructor(init: ModelInit<OrderAssignment>);
static copyOf(source: OrderAssignment, mutator: (draft: MutableModel<OrderAssignment>) => MutableModel<OrderAssignment> | void): OrderAssignment;
}
Two things to note:
-
id
shouldn't be there, it doesn't exist -
orderId
is omitted, but should be there
Experience the same problem. In my use case I'm trying to selectively sync DataStore against the "disappeared" id field which clearly won't work unless the field exists locally. Trying to find a work around but this seems like a bug. Did you find any solutions?
Hi,
I think this is worth to mention there is a workaround. Do not use amplify codegen
- use Amplify Studio instead.
Remove your relations from your datamodel and amplify push
, next configure your datamodel relations using the Amplify Studio web console and then update the datamodel from within the Amplify Studio.
After the update completes execute amplify pull
locally. Updated schema will be downloaded along with proper typescript model (having the missing ID's) - allowing you to reference and query your data 😃
I'm experiencing the same issue with Swift models. Here the point in which those fields are removed https://github.com/aws-amplify/amplify-codegen/blob/main/packages/appsync-modelgen-plugin/src/visitors/appsync-visitor.ts#L532 but sadly I don't understand the reason behind this choice.