Limiting SQL query to defined fields/columns
See original GitHub issueA full working demo can be found under https://github.com/somada141/demo-graphql-sqlalchemy-falcon.
Consider the following SQLAlchemy ORM class:
class Author(Base, OrmBaseMixin):
__tablename__ = "authors"
author_id = sqlalchemy.Column(
sqlalchemy.types.Integer(),
primary_key=True,
)
name_first = sqlalchemy.Column(
sqlalchemy.types.Unicode(length=80),
nullable=False,
)
name_last = sqlalchemy.Column(
sqlalchemy.types.Unicode(length=80),
nullable=False,
)
Simply wrapped in an SQLAlchemyObjectType as such:
class TypeAuthor(SQLAlchemyObjectType):
class Meta:
model = Author
and exposed through:
author = graphene.Field(
TypeAuthor,
author_id=graphene.Argument(type=graphene.Int, required=False),
name_first=graphene.Argument(type=graphene.String, required=False),
name_last=graphene.Argument(type=graphene.String, required=False),
)
@staticmethod
def resolve_author(
args,
info,
author_id: Union[int, None] = None,
name_first: Union[str, None] = None,
name_last: Union[str, None] = None,
):
query = TypeAuthor.get_query(info=info)
if author_id:
query = query.filter(Author.author_id == author_id)
if name_first:
query = query.filter(Author.name_first == name_first)
if name_last:
query = query.filter(Author.name_last == name_last)
author = query.first()
return author
A GraphQL query such as:
query GetAuthor{
author(authorId: 1) {
nameFirst
}
}
will cause the following raw SQL to be emitted (taken from the echo logs of the SQLA engine):
SELECT authors.author_id AS authors_author_id, authors.name_first AS authors_name_first, authors.name_last AS authors_name_last
FROM authors
WHERE authors.author_id = ?
LIMIT ? OFFSET ?
2018-05-24 16:23:03,669 INFO sqlalchemy.engine.base.Engine (1, 1, 0)
As one can see we may only want the nameFirst field, i.e., the name_first column but the entire row is fetched. Of course the GraphQL response only contains the requested fields, i.e.,
{
"data": {
"author": {
"nameFirst": "Robert"
}
}
}
but we have still fetched the entire row, which becomes a major issue when dealing with wide tables.
Is there a way to automagically communicate which columns are needed to SQLAlchemy so as preclude this form of over-fetching?
Issue Analytics
- State:
- Created 5 years ago
- Reactions:3
- Comments:15 (5 by maintainers)
Top Results From Across the Web
The Complete Guide to SQL Row Limiting and Top-N Queries
The SQL Limit feature allows for SQL row limiting and performing Top-N queries. Learn how to use the LIMIT feature and how to...
Read more >Limiting SQL query to defined fields/columns in Graphene ...
My question was answered on the GitHub issue (https://github.com/graphql-python/graphene-sqlalchemy/issues/134). The idea is to identify the ...
Read more >Using the SQL Limit Keyword - Navicat
The SQL LIMIT clause constrains the number of rows returned by a SELECT statement. For Microsoft databases like SQL Server or MSAccess, ...
Read more >SQL: SELECT LIMIT Statement - TechOnTheNet
The SQL SELECT LIMIT statement is used to retrieve records from one or more tables in a database and limit the number of...
Read more >SQL LIMIT | Basic SQL - Mode Analytics
As you might expect, the limit restricts how many rows the SQL query returns. ... idea of which fields you care about and...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

Should anyone land here wondering about implementation I got around to implementing my own version of the
get_query_fieldsfunction as such:which parses the AST into a
dictpreserving the structure of the query and (hopefully) matching the structure of the ORM.Running the
infoobject of a query like:produces
while a more complex query like this:
produces:
Now these dictionaries can be used to define what is a field on the primary-table (
Authorin this case) as they’ll have a value ofNonesuch asname_firstor a field on a relationship of that primary-table such as fieldtitleon thebooksrelationship.A simplistic approach to auto-applying those fields can take the form of the following function:
Hi, I didn’t find full answer, so I combined answers and made solution for “n+1”, but “cartesian product” appears.
extract_requested_fieldsfunction from @somada141, that converts requested fields to dictmakeLoadOnlyOptionsfunction, that converts dict to query optionsLoadOnlyConnectionField- if you don’t want custom class, you can use this example to resolve query manually