'Can I pass a dict to where() in SQLAlchemy?
Rather than selecting rows by a static set of columns, e.g.
stmt = select(User).where(and_(User.first_name == 'foo', User.last_name == 'bar'))
I would like to pass a dict with a variable set of columns, e.g.
cols = {'User.first_name': 'foo',
'User.last_name': 'bar',
'User.other_col': 'blah'}
stmt = select(User).where(cols)
Is something like this possible?
Solution 1:[1]
As I put in the comment, you can add to a statement after first defining it.
I feel a good example would be Flask, where you need to build a query based on inputs.
@app.route('/users', methods=['GET'])
def users_get():
"""Get matching users."""
stmt = select(User)
if request.args.get('username'):
stmt = stmt.where(User.username == request.args['username'])
if request.args.get('parent'):
stmt = stmt.where(User.parent.has(User.username == request.args['parent']))
if request.args.get('children'):
children = request.args['children'].split(',')
stmt = stmt.where(User.children.any(User.username.in_(children)))
matching_users = session.query(stmt).scalars()
return map(user_to_dict, matching_user)
Alternatively if you need to build up an OR
statement, just build up a list and add it all at once:
stmt = select(User)
exprs = []
if a:
exprs.append(User.username == a)
if b:
exprs.append(User.username == b)
if where:
stmt = stmt.where(or_(*exprs))
You said how you don't know the table structure until execution, depending on how you get the columns, perhaps something like this would work if you did getattrs?
stmt = select(User)
for k, v in get_column_values(User).items():
stmt = stmt.where(getattr(User, k) == v)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Peter |