I think I must have missed something basic here so hopefully this will be an easy fix. I've set up my graphql api with graphene and SQLalchemy and I can return all the data from my Postgres database. However, I can't figure out how to limit my results to return only one record.
Here's my schema object:
class Dataset(SQLAlchemyObjectType):
class Meta:
model = DatasetModel
interfaces = (graphene.relay.Node, )
And here's my query:
class Query(graphene.ObjectType):
node = graphene.relay.Node.Field()
all_datasets = SQLAlchemyConnectionField(Dataset.connection)
schema = graphene.Schema(query=Query)
What do I need to add/change to allow me to limit the results by the field datasetName
?
I tried adding the following function:
def resolve_dataset(root, info, datasetName):
return db_session.query(Dataset).filter_by(datasetName=datasetName).first()
The API still runs but when I try adding the search field to the graphql query, I get a syntax error. I also tried adding the line:
Base.query = db_session.query_property()
To my models.py
as suggested by the documentation but it didn't seem to make any difference.
Can someone explain what I missed? How do I limit my results by a value I supply to the api?
EDIT: Adding in information problem I encountered implementing the first suggested solution.
I added the resolved function below to my query class:
def resolve_all_datasets(root, info, **kwargs):
query = db_session.query(Dataset)
if kwargs.get('datasetName'):
query=query.filter_by(datasetName=kwargs['datasetName'])
return query
And then searched with the following query to my api endpoint:
{allDatasets(datasetName:"MyDataset"){
edges{
node{
abstract
}
}
}
}
But got:
{
"errors": [
{
"message": "Column expression or FROM clause expected, got <Dataset meta=<SQLAlchemyObjectTypeOptions name='Dataset'>>.",
"locations": [
{
"line": 2,
"column": 2
}
],
"path": [
"allDatasets"
]
}
],
"data": {
"allDatasets": null
}
}
CodePudding user response:
You should define resolve_all_datasets
resolver instead of resolve_dataset
(i cannot see dataset
field on your schema).
For an elegant solution you can use library:https://pypi.org/project/graphene-sqlalchemy-filter/
However you can override resolver manually:
class Query(graphene.ObjectType):
node = graphene.relay.Node.Field()
all_datasets = SQLAlchemyConnectionField(Dataset.connection, datasetName=graphene.String())
def resolve_all_datasets(root, info, **kwargs):
query = db_session.query(DatasetModel)
if kwargs.get('datasetName'):
query = query.filter_by(datasetName=kwargs['datasetName'])
return query
schema = graphene.Schema(query=Query)
Alternative solution to return only one dataset:
class Query(graphene.ObjectType):
node = graphene.relay.Node.Field()
dataset = graphene.Field(Dataset, datasetName=graphene.String(required=True))
def resolve_dataset(root, info, **kwargs):
return db_session.query(DatasetModel).filter_by(datasetName=kwargs['datasetName']).first()
schema = graphene.Schema(query=Query)