Can I chain where clauses conditionally?
Question:
I’m using Peewee as ORM extensively and within my DAO API layer I need to conditionally make a query narrower e.g.
query = UserModel.select().where(UserModel.last_name == last_name)
if first_name is not None:
query = query.where(UserModel.first_name == first_name)
# ... more conditions then
df = pd.DataFrame(query.dicts())
is this the most idiomatic way to conditionally make the queries narrower in Peewee or is there another way? Are there any pros and cons of doing this?
Answers:
I would suggest to doing first the dynamic condition and then calling where clause.
query = UserModel.select()
filtered = UserModel.last_name == last_name
if first_name is not None:
filtered &= UserModel.first_name == first_name
# ... more conditions then
# if some_cond:
# filtered &= some_other_cond
# if some_cond:
# filtered |= some_other_cond
# put one or other depending on
# the logic of your function
query = query.where(filtered)
df = pd.DataFrame(query.dicts())
Edit : fix an error in the code
Sure you can do this a couple ways:
# Chaining calls to .where() will AND the clauses together.
q = q.where(Model.field == 'something')
q = q.where(Model.other == 'another')
# Another option:
accum = []
accum.append(Model.field == 'something')
accum.append(Model.other == 'another')
q = q.where(*accum)
# Or you can explicitly AND them together:
q = q.where(reduce(operator.and_, accum))
Etc.
I’m using Peewee as ORM extensively and within my DAO API layer I need to conditionally make a query narrower e.g.
query = UserModel.select().where(UserModel.last_name == last_name)
if first_name is not None:
query = query.where(UserModel.first_name == first_name)
# ... more conditions then
df = pd.DataFrame(query.dicts())
is this the most idiomatic way to conditionally make the queries narrower in Peewee or is there another way? Are there any pros and cons of doing this?
I would suggest to doing first the dynamic condition and then calling where clause.
query = UserModel.select()
filtered = UserModel.last_name == last_name
if first_name is not None:
filtered &= UserModel.first_name == first_name
# ... more conditions then
# if some_cond:
# filtered &= some_other_cond
# if some_cond:
# filtered |= some_other_cond
# put one or other depending on
# the logic of your function
query = query.where(filtered)
df = pd.DataFrame(query.dicts())
Edit : fix an error in the code
Sure you can do this a couple ways:
# Chaining calls to .where() will AND the clauses together.
q = q.where(Model.field == 'something')
q = q.where(Model.other == 'another')
# Another option:
accum = []
accum.append(Model.field == 'something')
accum.append(Model.other == 'another')
q = q.where(*accum)
# Or you can explicitly AND them together:
q = q.where(reduce(operator.and_, accum))
Etc.