I have a table containing Posts, with a number of columns. id, title, author, tags, timestamp
I'm trying to use SQLAlchemy to sort/filter these posts by each of the columns. For example, a user can decide they want to see all posts from author
, with tags a, b, c
, ordered by timestamp
descending.
Is there a way to dynamically build a query starting from a simple sqlalchemy.select()
?
For example:
import sqlalchemy as sa
query = sa.select(models.Post)
if userProvidedAuthor:
query.filter(models.Post.author == userProvidedAuthor)
if userProvidedOrder:
if userProvidedDirection == 'asc':
query.order_by(userProvidedOrder.asc())
else:
query.order_by(userProvidedOrder.desc())
results = session.execute(query)
Obviously this example won't run, but I hope it illustrates what I'm trying to do.
Some things I've considered:
Any ideas/help would be appreciated. For context, I'm trying to build a blog site in Flask as a learning project.
Some chaining will work. I don't think it makes much sense sometimes but you just have to keep re-assigning the result.
import sqlalchemy as sa
query = sa.select(models.Post)
if userProvidedAuthor:
query = query.where(models.Post.author == userProvidedAuthor)
#...
The docs demonstrate how repeated calls to where()
produce an AND
here: the-where-clause
Usually it is better to just build up the major things yourself like conditions into a list then put them in all at once.
Like (untested but should work):
import sqlalchemy as sa
where_args = []
if userProvidedAuthor:
where_args.append(models.Post.author == userProvidedAuthor)
order_by_args = []
if userProvidedOrder == 'timestamp':
order_by_args.append(models.Post.timestamp)
#...
query = sa.select(models.Post).where(*where_args).order_by(*order_by_args)
#...
The SQLAlchemy 2.0
docs have a lot of great examples. The creator and maintainers put a lot of effort into them. Maybe try going through the tutorials while simultaneously working on the test project.