filter(or_(False)) throws exception
Let's just say upfront that this seems like an extreme edge-case so I'm okay if this ignored...
I'm currently developing a search API and am translating query terms into SQLA filters. I then compile the filters together and make an SQL query. Sometimes elements of the filter are or_
'ed together. I found that SQLA was smart enough that when an or_
received a single filter it understood and removed the "OR" component of the query.
So, I could do the following with no issues: filter(or_(*or_filters))
Sometimes I find that I get query terms that should basically cause the whole query to fail so I do that by inserting a False
into the filter. Doing a filter(False, ..snip.. )
works fine.
Since those two aspects work, I was surprised when doing filter(or_(False))
gave me an exception.
File "/sites/metrics_dev/env/lib/python3.4/site-packages/sqlalchemy/sql/elements.py", line 1941, in or_
return cls._construct(operators.or_, False_, True_, *clauses)
File "/sites/metrics_dev/env/lib/python3.4/site-packages/sqlalchemy/sql/elements.py", line 1857, in _construct
return clauses[0].self_group(against=operators._asbool)
AttributeError: 'bool' object has no attribute 'self_group'
This is in SQLA 1.0.6
Comments (5)
-
repo owner -
repo owner well, and_(False) works, so it would seem or_(False) should also
-
reporter As I said "extreme edge-case"... :)
What I'm doing is
filters(or_(*subfilters))
, and that fails only ifsubfilters == [False]
.I'll try
sqlalchemy.false()
instead as right now what I'm doing is testing if the length ofsubfilters
is greater than 1 before using theor_
. -
repo owner we should be able to go with this:
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 27ecce2..d3f5a73 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -1840,9 +1840,12 @@ class BooleanClauseList(ClauseList, ColumnElement): def _construct(cls, operator, continue_on, skip_on, *clauses, **kw): convert_clauses = [] - clauses = util.coerce_generator_arg(clauses) + clauses = [ + _expression_literal_as_text(clause) + for clause in + util.coerce_generator_arg(clauses) + ] for clause in clauses: - clause = _expression_literal_as_text(clause) if isinstance(clause, continue_on): continue
-
repo owner - changed status to resolved
- Fixed bug where coersion of literal
True
orFalse
constant in conjunction with :func:.and_
or :func:.or_
would fail with an AttributeError. fixes#3490
→ <<cset 3cfe3fd81d7c>>
- Log in to comment
ok why don't use use sqlalchemy.false() instead ?