I need the ability to override resolvers of model objects. I believe I was able to do this in previous versions of graphback during the alpha, and I did this with Prisma. It isn't working anymore. For example:
"""@model"""
type Companies {
id: ID!
test: Int!
}
test is not in the database, I am going to write a resolver for it. In the past I would overwrite that field in my resolvers object:
const {
typeDefs,
resolvers,
contextCreator
} = buildGraphbackAPI(model, {
dataProviderCreator: createKnexDbProvider(knexDB)
});
const newResolvers = {
...resolvers,
Companies: {
...resolvers.Companies,
test: () => 5
}
};
I would then take newResolvers and give it to Apollo Server. This doesn't work for some reason, and I keep getting the following error: "No result from database: Cannot find a result for companies with filter: {\"id\":\"1\"}"
Automatically generated comment to notify maintainers
/cc @craicoverflow, @machi1990, @wtrocki
Related to this: https://github.com/aerogear/graphback/issues/1432
The error we see is not related to resolver it is more than a database cannot be queried with provided id.
Looking at your snippet I do not see anything alarming so indeed, this is what @wtrocki says it is. Let us know how if this works when changing the requested id to something else.
The company that I am querying indeed exists in the database. For example, this query works:
query {
getCompanies(id: 1) {
id
}
}
and returns the following:
{
"data": {
"getCompanies": {
"id": "1"
}
}
}
But when I add the test field that has a custom resolver hooked up like I showed in previous comments:
query {
getCompanies(id: 1) {
id
test
}
}
This does not work, and I get the following result:
{
"errors": [
{
"message": "No result from database: Cannot find a result for companies with filter: {\"id\":\"1\"}",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"getCompanies"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: No result from database: Cannot find a result for companies with filter: {\"id\":\"1\"}",
" at KnexDBDataProvider.<anonymous> (/home/lastmjs/development/jill/jills-office-node/node_modules/@graphback/runtime-knex/src/KnexDBDataProvider.ts:75:13)",
" at Generator.throw (<anonymous>)",
" at rejected (/home/lastmjs/development/jill/jills-office-node/node_modules/tslib/tslib.js:113:69)",
" at processTicksAndRejections (internal/process/task_queues.js:85:5)"
]
}
}
}
],
"data": {
"getCompanies": null
}
}
Thanks for checking @lastmjs, I fully understand now, previous I was thinking that the field test is in the database also. But now I understand. It might be a bug since from the ResolversInfo we'll issue a query like
select id, test from companies where id = xxx
Which fails with a missing column error.
I am thinking maybe we can introduce a way to ignore some fields from database selection? I know we have @db(skip: true) that's ignores a field only when running migrations.
/cc @craicoverflow @wtrocki
The issue seems to run even deeper, and based on my limited knowledge of Graphback's internals, I would say this has to do with how the dataloader attempts to resolve relations (probably similar to what you're saying @machi1990). I have a custom query that looks like this:
Query {
fetchLiveQueue: [Incoming_queue_items!]!
}
""" @model """
type Incoming_queue_items {
id: ID!
"""
@oneToOne(key: 'call_id')
"""
call: Calls!
created_at: DateTime!
handled_at: DateTime
incoming_call_type: INCOMING_CALL_TYPE!
"""
@oneToOne(key: 'pod_id')
"""
pod: Pods!
updated_at: DateTime!
user_call_sid: String!
}
When I execute the following query:
query {
fetchLiveQueue {
pod {
id
}
}
}
I get the following error:
{
"errors": [
{
"message": "No result from database: Cannot find a result for pods with filter: {}",
"locations": [
{
"line": 3,
"column": 5
}
],
"path": [
"fetchLiveQueue",
0,
"pod"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: No result from database: Cannot find a result for pods with filter: {}",
" at KnexDBDataProvider.<anonymous> (/var/task/node_modules/@graphback/runtime-knex/dist/KnexDBDataProvider.js:73:23)",
" at Generator.throw (<anonymous>)",
" at rejected (/var/task/node_modules/tslib/tslib.js:113:69)",
" at processTicksAndRejections (internal/process/task_queues.js:97:5)"
]
}
}
}
],
"data": null
}
fetchLiveQueue has a completely custom resolver, and thus should be completely outside of the scope of Graphback's resolvers and dataloader pattern. I have found a workaround for this, but it requires me to create custom types outside of the the types I already have marked with @model
Thank you @lastmjs for digging deeper.
Glad that you have found a workaround for now, do you mind posting a code snippet here in the issuse so that it could be useful for others users while the team is further triaging this issue? Thank you.
Sure, the workaround is simple. Just make a custom type without a @model annotation.
Query {
fetchLiveQueue: [FetchLiveQueueIncomingQueueItems!]!
}
# Simplified example, but just add the fields that you need
type FetchLiveQueueIncomingQueueItems {
id: ID!
created_at: DateTime!
pod: FetchLiveQueueIncomingQueuePods!
}
type FetchLiveQueueIncomingQueuePods {
id: ID!
}
""" @model """
type Incoming_queue_items {
id: ID!
"""
@oneToOne(key: 'call_id')
"""
call: Calls!
created_at: DateTime!
handled_at: DateTime
incoming_call_type: INCOMING_CALL_TYPE!
"""
@oneToOne(key: 'pod_id')
"""
pod: Pods!
updated_at: DateTime!
user_call_sid: String!
}
I am thinking maybe we can introduce a way to ignore some fields from database selection? I know we have
@db(skip: true)that's ignores a field only when running migrations.
@machi1990 yes that would make sense. I touched on this in https://github.com/aerogear/graphback/issues/1023 - if there was an @ignore annotation this could be used for both cases - ignore a field not in the database and ignore a field in the database table.
@craicoverflow cool, @ignore makes sense. Let me add a comment in that issue.
I'm not sure @ignore would solve the problem I'm having, unless you put @ignore on the custom query fetchLiveQueue. In my example above, Incoming_queue_items is in the database, and the Graphback-generated queries should use the database and do batching and dataloader things. But, for my custom queries I am just using Incoming_queue_items as a type, and fetching the data myself. I shouldn't have to use @ignore anywhere on Incoming_queue_items in this case, just in fetchLiveQueue. Seems @ignore is not an elegant solution to this.
@lastmjs the @ignore annotation will be placed directly on the fields that should not be loaded from the database.
"""@model""" type Companies { id: ID! test: Int! }
testis not in the database, I am going to write a resolver for it. In the past I would overwrite that field in my resolvers object:
For example, you could use it in the model above as:
graphql
"""@model"""
type Companies {
id: ID!
"""
@ignore
"""
test: Int!
}
and it will:
test field from the query issued in database, thus avoid a missing column error which resulted in the issue you were seeing.test field is not in the database. This will avoid similar errors during create/update/deletetest field will be omitted from the generate CompaniesFilterInput, again for the same reason.All these points above are due to the fact that test is a transient field and Graphback should not attempt to manage it in either way.
Going to this https://github.com/aerogear/graphback/issues/1843#issuecomment-671503126, maybe the @ignore field will not be appropriate ( I am yet to find out why you are having this issue). Do you mind sharing in a sample code the query sent to the database? There are two possibilities:
Having a small code snippet in how the query is issued will be helpfully in understanding this second issue. Thank you.
Hey, is the example here good enough? https://github.com/aerogear/graphback/issues/1843#issuecomment-671503126
This is the query:
query {
fetchLiveQueue {
pod {
id
}
}
}
The example schema is in that comment
Thank you @lastmjs I'll try to setup something similar in an attempt to reproduce the issue.
Hey, thanks for fixing part of the issue, but a large part of my issue as explained in multiple comments above will not be fixed by this. I think this issue should be reopened or perhaps the remaining part of the issue should be moved to a new issue
Hey, thanks for fixing part of the issue, but a large part of my issue as explained in multiple comments above will not be fixed by this. I think this issue should be reopened or perhaps the remaining part of the issue should be moved to a new issue
Hi @lastmjs this indeed fix the issue where you have a field that is not in database.
but a large part of my issue as explained in multiple comments above will not be fixed by this. I think this issue should be reopened or perhaps the remaining part of the issue should be moved to a new issue
As for this issue, I believe you are talking about this https://github.com/aerogear/graphback/issues/1843#issuecomment-671503126 quoted below:
The issue seems to run even deeper, and based on my limited knowledge of Graphback's internals, I would say this has to do with how the dataloader attempts to resolve relations (probably similar to what you're saying @machi1990). I have a custom query that looks like this:
Query { fetchLiveQueue: [Incoming_queue_items!]! } """ @model """ type Incoming_queue_items { id: ID! """ @oneToOne(key: 'call_id') """ call: Calls! created_at: DateTime! handled_at: DateTime incoming_call_type: INCOMING_CALL_TYPE! """ @oneToOne(key: 'pod_id') """ pod: Pods! updated_at: DateTime! user_call_sid: String! }When I execute the following query:
query { fetchLiveQueue { pod { id } } }I get the following error:
{ "errors": [ { "message": "No result from database: Cannot find a result for pods with filter: {}", "locations": [ { "line": 3, "column": 5 } ], "path": [ "fetchLiveQueue", 0, "pod" ], "extensions": { "code": "INTERNAL_SERVER_ERROR", "exception": { "stacktrace": [ "Error: No result from database: Cannot find a result for pods with filter: {}", " at KnexDBDataProvider.<anonymous> (/var/task/node_modules/@graphback/runtime-knex/dist/KnexDBDataProvider.js:73:23)", " at Generator.throw (<anonymous>)", " at rejected (/var/task/node_modules/tslib/tslib.js:113:69)", " at processTicksAndRejections (internal/process/task_queues.js:97:5)" ] } } } ], "data": null }
fetchLiveQueuehas a completely custom resolver, and thus should be completely outside of the scope of Graphback's resolvers and dataloader pattern. I have found a workaround for this, but it requires me to create custom types outside of the the types I already have marked with @model
From my understanding, you have a custom resolver fetchLiveQueue loading a list of Incoming_queue_items using a graphback service.
From looking at the error message, its seems to me that you are attempting to load pods using a services.Pods.findOne({}) is this correct ? If so, can you share with me the rest of your typescript snippets ( resolver code ) so that I can debug it further.
Out of curiosity, does the Pods type contain a field that's not in the database?
Thanks.
Also, I am re-opening this, for further investigation.
fetchLiveQueuehas a completely custom resolver, and thus should be completely outside of the scope of Graphback's resolvers and dataloader pattern.
@lastmjs when you say that fetchLiveQueue has a complete custom resolver, since this resolver returns a Incoming_queue_items type, I've additional questons regarding your custom resolver:
Incoming_queue_items.pod resolver with your own? query {
fetchLiveQueue {
pod {
id
}
}
}
what result do you get in your custom resolver before the resolution of the oneToOne relationship between Incoming_queue_items and Pods via the generated Incoming_queue_items.pod?
If you do not mind, can you send me the actual error you are seeing from the database. To get it, add the catched error in this line: https://github.com/aerogear/graphback/blob/7d4f80c47cb5ff0c58da9dd493c424ffd0015fcb/packages/graphback-runtime-knex/src/KnexDBDataProvider.ts#L72 (you might have the transpiled file). Once that is done restart the server and and do the query again.
Thanks once again.
@lastmjs ping, I was thinking about this issue again and was wondering if you can take a look at https://github.com/aerogear/graphback/issues/1843#issuecomment-678524738 and https://github.com/aerogear/graphback/issues/1843#issuecomment-678554357, thanks :-)
Closing as this looks to be resolved, but reopen if I am wrong on that.