Вместо того, чтобы выбирать строки по статическому набору столбцов, например.
stmt = select(User).where(and_(User.first_name == 'foo', User.last_name == 'bar'))
Я хотел бы передать dict с переменным набором столбцов, например.
cols = {'User.first_name': 'foo',
'User.last_name': 'bar',
'User.other_col': 'blah'}
stmt = select(User).where(cols)
Возможно ли что-то подобное?
Привет @Peter, мой вариант использования - это в основном абстракция. Возможность построить запрос, который не должен знать структуру таблицы до выполнения. Ваше предложение может привести меня туда, куда я хочу. Спасибо за ответ.
О, круто, опубликую ответ с примером того, как я использую этот способ с флягой :)
Как я сказал в комментарии, вы можете добавить к оператору после его первого определения.
Я чувствую, что хорошим примером может быть Flask, где вам нужно построить запрос на основе входных данных.
@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)
В качестве альтернативы, если вам нужно создать утверждение OR
, просто создайте список и добавьте его все сразу:
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))
Вы сказали, что вы не знаете структуру таблицы до выполнения, в зависимости от того, как вы получаете столбцы, возможно, что-то подобное сработает, если вы сделаете getattrs?
stmt = select(User)
for k, v in get_column_values(User).items():
stmt = stmt.where(getattr(User, k) == v)
Каков именно ваш вариант использования? Вам не нужно делать все сразу, если это помогает, например
stmt = select(User).where(User.first_name == 'foo'); if condition: stmt = stmt.where(User.last_name == 'bar')