Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to construct a slightly more complex filter using "or_" or "and_" in SQLAlchemy

I'm trying to do a very simple search from a list of terms

terms = ['term1', 'term2', 'term3'] 

How do I programmatically go through the list of terms and construct the conditions from the list of terms so that I can make the query using filter and or_ or _and?

query.filter(or_(#something constructed from terms)) 
like image 770
Andrew Kou Avatar asked Apr 20 '10 21:04

Andrew Kou


People also ask

What is lazy dynamic SQLAlchemy?

lazy = 'dynamic': When querying with lazy = 'dynamic', however, a separate query gets generated for the related object. If you use the same query as 'select', it will return: You can see that it returns a sqlalchemy object instead of the city objects.

What is _sa_instance_state in SQLAlchemy?

_sa_instance_state is a non-database-persisted value used by SQLAlchemy internally (it refers to the InstanceState for the instance.

What is the difference between in and or in SQLAlchemy?

Also "IN" is limited to a set of ~1000 entries, while "OR" is not. SQLAlchemy overloads the bitwise operators &, | and ~ so instead of the ugly and hard-to-read prefix syntax with or_ () and and_ () (like in Bastien's answer) you can use these operators: .filter ( (AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))

How can I create complex conditions (called'query filters'?

How can I create complex conditions (called ' Query Filters ') by nesting or indenting them together, and using AND and OR? This can be done differently depending on whether your Preferences > Web Intelligence > Modify are Applet or HTML. HTML - Special Nested Filters button available. Open the report in DESIGN mode.

How do I create a filter on multiple objects at once?

Click the Edit Data Provider icon and the Query Panel opens. Drag the Object that you want to filter on into the Query Filters Pane and drop it anywhere below the pre-existing filters. Drag your second Object into the Query Filters Pane and just slightly overlap the first one and then drop it. Both Objects should indent.

How do I create a nested query filter in SQL?

Drag an Object that you want to filter on and drop it when you see the red line next to OR. Drag the second object and drop it when you see the red line appear above or below the previous filter. You now have a nested query filter.


1 Answers

If you have a list of terms and want to find rows where a field matches one of them, then you could use the in_() method:

terms = ['term1', 'term2', 'term3'] query.filter(Cls.field.in_(terms)) 

If you want to do something more complex, then or_() and and_() take ClauseElement objects as parameters. ClauseElement and its subclasses basically represent the SQL AST of your query. Typically, you create clause elements by invoking a comparison operator on Column or InstrumentedAttribute objects:

# Create the clause element clause = (users_table.columns['name'] == "something") #    you can also use the shorthand users_table.c.name  # The clause is a binary expression ... print(type(clause)) #    <class 'sqlalchemy.sql.expression._BinaryExpression'> # ... that compares a column for equality with a bound value. print(type(clause.left), clause.operator, type(clause.right)) #    <class 'sqlalchemy.schema.Column'>, <built-in function eq>, #    <class 'sqlalchemy.sql.expression._BindParamClause'>  # str() compiles it to SQL print(str(clause))  # users.name = ?  # You can also do that with ORM attributes clause = (User.name == "something") print(str(clause)) # users.name = ? 

You can handle clause elements representing your conditions like any Python objects, put them into lists, compose them into other clause elements, etc. So you can do something like this:

# Collect the separate conditions to a list conditions = [] for term in terms:     conditions.append(User.name == term)  # Combine them with or to a BooleanClauseList condition = or_(*conditions)  # Can now use the clause element as a predicate in queries query = query.filter(condition) # or to view the SQL fragment print(str(condition)) #    users.name = ? OR users.name = ? OR users.name = ? 
like image 180
Ants Aasma Avatar answered Sep 23 '22 16:09

Ants Aasma