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

Is it possible to access createdAt and updatedAt? #401

Closed
michaelcaterisano opened this issue Nov 6, 2018 · 40 comments · Fixed by #4149
Closed

Is it possible to access createdAt and updatedAt? #401

michaelcaterisano opened this issue Nov 6, 2018 · 40 comments · Fixed by #4149
Labels
feature-request Request a new feature graphql-transformer-v1 Issue related to GraphQL Transformer v1 pending-release Code has been merged but pending release

Comments

@michaelcaterisano
Copy link

** Which Category is your question related to? **
amplify schema and DynamoDB

** What AWS Services are you utilizing? **
amplify-js, amplify-cli, AppSync, DynamoDb

** Provide additional details e.g. code snippets **

I've noticed that the Dynamo DB fields createdAt and updatedAt are automatically generated when I amplify push my graphql schema, but I can't figure out a way to query these fields. Is it possible, or should I add my own custom createdAt and updatedAt fields? Perhaps with different names? Just wondering what the best way to approach this is.

Without date (createdAt and updatedAt automatically generated in DynamoDB):

type Category @model @auth(rules: [{allow: owner}]) {
  id: ID!
  name: String!
  products: [Product] @connection(name: "CategoryProducts")
}

Solution 1 (add createdOn field, so not to override auto createdAt field):

type Category @model @auth(rules: [{allow: owner}]) {
  id: ID!
  createdOn: AWSDateTime!
  name: String!
  products: [Product] @connection(name: "CategoryProducts")
}

Solution 2 (override createdAt with custom field of same name):

type Category @model @auth(rules: [{allow: owner}]) {
  id: ID!
  createdAt: AWSDateTime!
  name: String!
  products: [Product] @connection(name: "CategoryProducts")
}
@mikeparisstuff
Copy link
Contributor

Solution 2 will work but you will need to make the fields nullable or else all Create/Update inputs will require them even though they are being set on the server.

@michaelcaterisano
Copy link
Author

Meaning not required, like this?

type Category @model @auth(rules: [{allow: owner}]) {
  id: ID!
  createdAt: AWSDateTime
  name: String!
  products: [Product] @connection(name: "CategoryProducts")
}

This works for me!

I tried it the other way, createdAt: AWSDateTime!, and was able to Create, but the date I entered was ignored, and the current DateTime was set on the server.

@kaustavghosh06 kaustavghosh06 added graphql-transformer-v1 Issue related to GraphQL Transformer v1 question General question labels Nov 21, 2018
@hisham
Copy link
Contributor

hisham commented Nov 30, 2018

One minor thing is as soon as you add createdAt to the model in the schema, then the transformer will add this to the CreateCategoryInput and UpdateCategoryInput, potentially allowing the client to pass a new createdAt and modify the createdAt date on an update call.

@mikeparisstuff
Copy link
Contributor

These are good points. I think we should revisit this topic. This feature was added to make keeping track of timestamps easy but I agree that we should have the ability to tweak timestamp behavior. We are trying to make as few backwards incompatible changes as possible so what if we added a "timestamps" argument to @model.

# The default timestamps value would be
type Post @model(timestamps: {create: "createdAt", update: "updatedAt" }) {
  id: ID!
}

We would then remove those timestamp fields from the CreatePostInput and UpdatePostInput input objects.

You could also turn timestamps off altogether

type Post @model(timestamps: null) {
  id: ID!
}

And we would do nothing concerning timestamps. No input augmentation or otherwise?

Would love to hear your thoughts.

@michaelcaterisano
Copy link
Author

@mikeparisstuff Your solution would work for me as long as it would then be possible to query/filter by different timestamps. I think that's what you're proposing would be possible.

@robert-moore
Copy link

Any update on a timeline for this?

@tedkimzikto
Copy link

anyone?

@kareemsuhail
Copy link

take a look at this issue issue#355@aws amplify docs
@tedkimzikto @robert-moore

@janhesters
Copy link

@mikeparisstuff Is this implemented?

@ohsik
Copy link

ohsik commented Apr 14, 2019

Any updates on this? will it be possible to query createdAt?

@acrabb
Copy link

acrabb commented Apr 23, 2019

bump :)

@austinamorusocfc
Copy link

@jordanranz @mikeparisstuff Is there any head way on this because the thought of having to manage this from the client seems problematic. Also tangental but similar is the idea of an audit log for objects?

@yareyaredesuyo
Copy link

This is very confusing.

In amplify docs, createdAt and updatedAt uses String 🤔🤔🤔🤔🤔

https://aws-amplify.github.io/docs/cli/graphql

maybe use DateType(in appsync, AWSDateTime? ) related type shoud be better.

https://docs.aws.amazon.com/appsync/latest/devguide/scalars.html

@oreillyross
Copy link

Would love to see a directive type approach @createdat or @updatedAt like Prisma introduced in April this year, seems a nice tradeoff but still easy to implement for what is a pretty common need for apps. https://www.prisma.io/blog/datamodel-v11-lrzqy1f56c90

@phishy
Copy link
Contributor

phishy commented May 27, 2019

Where did this land?

@gitzhouxinyu1
Copy link

Any updates?

@mtliendo
Copy link

One minor thing is as soon as you add createdAt to the model in the schema, then the transformer will add this to the CreateCategoryInput and UpdateCategoryInput, potentially allowing the client to pass a new createdAt and modify the createdAt date on an update call.

@hisham Would this be solved by adding a field-level auth directive so that the client wouldn't have the ability to modify?

createdAt: AWSDateTime @auth(rules: [{ allow: owner, operations: [read] }])

@hisham
Copy link
Contributor

hisham commented Aug 4, 2019

One minor thing is as soon as you add createdAt to the model in the schema, then the transformer will add this to the CreateCategoryInput and UpdateCategoryInput, potentially allowing the client to pass a new createdAt and modify the createdAt date on an update call.

@hisham Would this be solved by adding a field-level auth directive so that the client wouldn't have the ability to modify?

createdAt: AWSDateTime @auth(rules: [{ allow: owner, operations: [read] }])

You'd have to try it and look at the vtl resolver code to see how the auth logic is handled. Worth a try for sure.

@jkeys-ecg-nmsu
Copy link

#401 (comment)

My question is why not just assume these things on behalf of us developers and build it in as the default case? Even with ledgers and other timestream databases it is still a common use case to query for the n most recent records in a given partition. The CLI should just detect that DynamoDB is the backing data source -- should be easy at the moment ;) -- and generate queries with createdAt and updatedAt fields by default if that's the case. The CLI should also prompt to generate local indexes (with warning about constraints on size) on createdAt or updatedAt.

I'd much rather the core Amplify developers focus on the default developer case (this may or may not be considered opinionated) and take edge cases as feature requests, so that requests like OP don't drop through the cracks. Workarounds should not be required, they should be made the default case.

IMO, the Amplify CLI should be a tool for enforcing best practices with AWS services anyway. Encouraging developers to conform to a sane default while providing escape hatches should be the default.

@murray-minito
Copy link

This is one of those issues that makes me worry about using Amplify. I am commenting to keep the heat on.

This is a really basic feature that should have been in from the start.

@contractorwolf
Copy link

where are we on this issue? I want this feature as well (to add my 2 cents)

@domezi
Copy link

domezi commented Apr 28, 2020

I agree with @murray-minito, please keep it up!

@undefobj
Copy link
Contributor

Hi we've been investigating this issue the past couple weeks and are working on it. No ETA but we're actively looking into a fix.

yuth added a commit that referenced this issue Apr 30, 2020
Expose createdAt and updatedAt automatically in the transformed schema. Added capability to change
the createdAt and updatedAt field names using timestamps

fix #401
yuth added a commit to yuth/amplify-cli that referenced this issue May 12, 2020
Expose createdAt and updatedAt automatically in the transformed schema. Added capability to change
the createdAt and updatedAt field names using timestamps

fix aws-amplify#401
yuth added a commit that referenced this issue May 14, 2020
… model (#4149)

Expose createdAt and updatedAt automatically in the transformed schema. Added capability to change
the createdAt and updatedAt field names using timestamps configuration

fix #401
@yuth yuth added the pending-release Code has been merged but pending release label May 14, 2020
@yuth
Copy link
Contributor

yuth commented May 18, 2020

This issue has been fixed and available in Amplify CLI v 4.20.0. For more details refer to @model directive usage docs

@emmafass
Copy link

@yuth Thank you for this fix! I came across it today and I am trying it out. I have a type called Suggestion that previously did not set createdAt or updatedAt (it just used the defaults).

I am now using @model(timestamps:{createdAt: "createdOn", updatedAt: "updatedOn"}) on this Suggestion type. Adding a new suggestion is working great, and I am able to view createdOn when I query the new Suggestion.

However, when I try to list all Suggestions, I get an error because the old Suggestions in my DB do not have createdOn set.

Cannot return null for non-nullable type: 'AWSDateTime' within parent 'Suggestion' (/listSuggestions/items[1]/createdOn)

When I try to update an old Suggestion, I get the error:

ObjectField{name='createdOn', value=StringValue{value='2020-04-29T00:04:47.073Z'}}]}' contains a field not in 'UpdateSuggestionInput': 'createdOn' @ 'updateSuggestion'"

which makes sense because the documentation makes it seem like the newly named values still mostly function like createdAt and updatedAt.

My question is how can I efficiently update the data I already have in production so that I can make use of the new @model directive?

@stayingcool
Copy link

How about this functionality for RDS/Aurora? As of now, I'm creating the table fields manually. It'll be great to have this automatically taken care of by amplify.

@DevTGhosh
Copy link

DevTGhosh commented Jan 5, 2021

@yuth after updating the model with @model(timestamps: { createdAt: "createdOn", updatedAt: "updatedOn" }) and running amplify codegen models I still can't see the new fields when using it with datastore. I am however able to view the createdOn and updatedOn on app sync console. Any idea on how to solve this?

Backend api Schema

type Clients
  @model(timestamps: { createdAt: "createdOn", updatedAt: "updatedOn" })
  @auth(
    rules: [{ allow: groups, groups: ["companyAdmin"], operations: [create, read, update, delete] }]
  ) {
  id: ID!
  name: String!
  email: String
  tenantId: [ID!]
}

This is what the datastore schema looks after running amplify codegen models

export const schema = {
    "models": {
        "Clients": {
            "name": "Clients",
            "fields": {
                "id": {
                    "name": "id",
                    "isArray": false,
                    "type": "ID",
                    "isRequired": true,
                    "attributes": []
                },
                "name": {
                    "name": "name",
                    "isArray": false,
                    "type": "String",
                    "isRequired": true,
                    "attributes": []
                },
                "email": {
                    "name": "email",
                    "isArray": false,
                    "type": "String",
                    "isRequired": false,
                    "attributes": []
                },
                "tenantId": {
                    "name": "tenantId",
                    "isArray": true,
                    "type": "ID",
                    "isRequired": true,
                    "attributes": [],
                    "isArrayNullable": true
                }
            },
            "syncable": true,
            "pluralName": "Clients",
            "attributes": [
                {
                    "type": "model",
                    "properties": {
                        "timestamps": {
                            "createdAt": "createdOn",
                            "updatedAt": "updatedOn"
                        }
                    }
                },
                {
                    "type": "auth",
                    "properties": {
                        "rules": [
                            {
                                "groupClaim": "cognito:groups",
                                "provider": "userPools",
                                "allow": "groups",
                                "groups": [
                                    "companyAdmin"
                                ],
                                "operations": [
                                    "create",
                                    "read",
                                    "update",
                                    "delete"
                                ]
                            }
                        ]
                    }
                }
            ]
        }
    },
    "enums": {},
    "nonModels": {},
    "version": "af6a903d3f7a75d2403d0fc2dac75a7a"
};

@patrickcze
Copy link

@DevTGhosh I am having the exact same issue as well.

@yuth
Copy link
Contributor

yuth commented Jan 5, 2021

A quick workaround is to add these fields to your type and you should have them accessible in data store schema.

@DevTGhosh
Copy link

DevTGhosh commented Jan 6, 2021

@patrickcze yeah as mentioned above just add the createdOn field to the model

type Post
  @model(timestamps: { createdAt: "createdOn", updatedAt: "updatedOn" }) {
  id: ID!
  title: String!
  tags: [String!]!
  createdOn: AWSDateTime!
  updatedOn: AWSDateTime!
}

@yuth Thanks for helping.

@rraczae
Copy link

rraczae commented Feb 12, 2021

This does not work with DataStore. Adding the field "manually" gives you access but updatedOn does not change automatically.

@patrickcze
Copy link

@yuth @DevTGhosh thanks for the reply, after making the same changes on your side have you seen errors like this?

DataStore - Skipping incoming subscription. Messages: Cannot return null for non-nullable type: 'AWSTimestamp' within parent 'ModelV1' (/onUpdateModelV1/_lastChangedAt)

@sherl0cks
Copy link

This does not work with DataStore. Adding the field "manually" gives you access but updatedOn does not change automatically.

@yuth I think this is important feedback. There are a lot of use cases where developers want to be able to query / display createdAt / updatedAt but do not want the responsibility of managing the timestamps themselves. This does not appear possible with the current timestamps field on the @model directive.

@kneekey23
Copy link

kneekey23 commented Mar 16, 2021

FYI @sherl0cks the codegen team is tracking an issue for this bug here as we agree it should be something you can read from on the front end in your generated models.

@sherl0cks
Copy link

@kneekey23 much appreciated!

@github-actions
Copy link

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 25, 2021
@josefaidt josefaidt added feature-request Request a new feature and removed enhancement labels Sep 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature-request Request a new feature graphql-transformer-v1 Issue related to GraphQL Transformer v1 pending-release Code has been merged but pending release
Projects
None yet
Development

Successfully merging a pull request may close this issue.