From 36949938e83f1e3096d24b74d33f19512d014520 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 10 Apr 2019 11:51:27 -0400 Subject: [PATCH] Don't use and_() inside of Query.filter_by Adjusted the :meth:`.Query.filter_by` method to not call :func:`.and()` internally against multiple criteria, instead passing it off to :meth:`.Query.filter` as a series of criteria, instead of a single criteria. This allows :meth:`.Query.filter_by` to defer to :meth:`.Query.filter`'s treatment of variable numbers of clauses, including the case where the list is empty. In this case, the :class:`.Query` object will not have a ``.whereclause``, which allows subsequent "no whereclause" methods like :meth:`.Query.select_from` to behave consistently. Fixes: #4606 Change-Id: Ifc8cdbf13accca2236068ef70114a7c35ab159ff --- doc/build/changelog/unreleased_13/4606.rst | 12 ++++++++++++ lib/sqlalchemy/orm/query.py | 2 +- test/orm/test_query.py | 9 +++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 doc/build/changelog/unreleased_13/4606.rst diff --git a/doc/build/changelog/unreleased_13/4606.rst b/doc/build/changelog/unreleased_13/4606.rst new file mode 100644 index 0000000000..6bdfa8a5f4 --- /dev/null +++ b/doc/build/changelog/unreleased_13/4606.rst @@ -0,0 +1,12 @@ +.. change:: + :tags: bug, orm + :tickets: 4606 + + Adjusted the :meth:`.Query.filter_by` method to not call :func:`.and()` + internally against multiple criteria, instead passing it off to + :meth:`.Query.filter` as a series of criteria, instead of a single criteria. + This allows :meth:`.Query.filter_by` to defer to :meth:`.Query.filter`'s + treatment of variable numbers of clauses, including the case where the list + is empty. In this case, the :class:`.Query` object will not have a + ``.whereclause``, which allows subsequent "no whereclause" methods like + :meth:`.Query.select_from` to behave consistently. diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 9544b7d117..5d340654cd 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -1791,7 +1791,7 @@ class Query(object): _entity_descriptor(self._joinpoint_zero(), key) == value for key, value in kwargs.items() ] - return self.filter(sql.and_(*clauses)) + return self.filter(*clauses) @_generative(_no_statement_condition, _no_limit_offset) def order_by(self, *criterion): diff --git a/test/orm/test_query.py b/test/orm/test_query.py index 8f962d5811..b31647a725 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -2880,6 +2880,15 @@ class FilterTest(QueryTest, AssertsCompiledSQL): checkparams={"email_address_1": "ed@ed.com", "name_1": "ed"}, ) + def test_empty_filters(self): + User = self.classes.User + sess = create_session() + + q1 = sess.query(User) + + is_(None, q1.filter().whereclause) + is_(None, q1.filter_by().whereclause) + def test_filter_by_no_property(self): addresses = self.tables.addresses sess = create_session() -- 2.47.2