1

For some reason, I can't figure out how to simply find a specific piece of data in my SQLAlchemy database.

In the graphene-python documentation it simply does this query to match the id (which is a string):

book(id: "Qm9vazow") {
    id
    title
}

Now here's my Flask-Graphene-SQLAlchemy code for my BookSchema and I want to find a specific title instead of an ID:

class BookModel(db.Model):
    __table__ = db.Model.metadata.tables['books_book']

# Schema Object
class BookSchema(SQLAlchemyObjectType):
    class Meta:
        model = BookModel
        interfaces = (relay.Node, )

# Connection
class BookConnection(relay.Connection):
    class Meta:
        node = BookSchema

# GraphQL query
class Query(graphene.ObjectType):
    node = relay.Node.Field()
    allBooks = SQLAlchemyConnectionField(BookConnection)


schema = graphene.Schema(query=Query, types=[BookSchema])

When I run this query, everything is fine and returns 3 book titles:

{
    "query": "{ allBooks(first: 3) { edges { node { title } } } }"
}

However, once I try to match a specific title, it stops working. For example:

# I tried all these queries, none worked
1. { allBooks(title: \"some book title\") { edges { node { title } } } }
2. { allBooks(title: \"some book title\") { title }
3. { allBooks(title: 'some book title') { edges { node { title } } } }

The error: "Unknown argument \"title\" on field \"allBooks\" of type \"Query\"."

I must be making a small error that I'm not seeing, but I can't figure it out. I've spent hours trying to figure this out.

Question: How can I match the title and have it return the object? What am I doing wrong?

davidism
  • 121,510
  • 29
  • 395
  • 339
Phil
  • 3,342
  • 5
  • 28
  • 50

1 Answers1

3

Figured it out! See changes below.

class Query(graphene.ObjectType):
    node = relay.Node.Field()
    all_books = SQLAlchemyConnectionField(BookConnection)

    # Added this
    find_book = graphene.Field(BookSchema, title = graphene.String())

    def resolve_find_book(self, info, title):
      query = BookSchema.get_query(info)
      return query.filter(BookModel.title == title).first()

And my GraphQL query looks like this:

{
    "query": "{ findBook(title: \"some book title\") { title } }"
}

Hope this helps someone in the future!

Phil
  • 3,342
  • 5
  • 28
  • 50
  • Seems like this should also be doable by providing a `filter_fields` parameter as shown in the [docs](https://docs.graphene-python.org/projects/django/en/latest/filtering/#filtering) – Daniel Rearden Jul 07 '19 at 09:51
  • 1
    Looks like this solution would work for Django based apps. I'm using Flask for mine – Phil Jul 07 '19 at 09:56