Skip to content

Commit c8786ea

Browse files
authored
Merge pull request #11 from Overseas-Student-Living/allow-field-based-queries
Allow field or aggregate based queries
2 parents 5bf898f + 4d21c52 commit c8786ea

File tree

6 files changed

+69
-4
lines changed

6 files changed

+69
-4
lines changed

CHANGELOG.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ versions, where semantic versioning is used: *major.minor.patch*.
66

77
Backwards-compatible changes increment the minor version number only.
88

9+
10+
Version 0.4.0
11+
-------------
12+
13+
Released 2017-06-21
14+
15+
* Adds support for queries based on model fields or aggregate functions.
16+
917
Version 0.3.0
1018
-------------
1119

README.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ Then we can apply filters to that ``query`` object (multiple times):
5151
5252
result = filtered_query.all()
5353
54+
Note that we can also apply filters to queries defined by fields or functions:
55+
56+
.. code-block:: python
57+
58+
query_alt_1 = self.session.query(Foo.id, Foo.name)
59+
query_alt_2 = self.session.query(func.count(Foo.id))
60+
61+
5462
Sort
5563
----
5664

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
setup(
1414
name='sqlalchemy-filters',
15-
version='0.3.0',
15+
version='0.4.0',
1616
description='A library to filter SQLAlchemy queries.',
1717
long_description=readme,
1818
author='Student.com',

sqlalchemy_filters/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@ def get_query_models(query):
3737
A dictionary with all the models included in the query.
3838
"""
3939
return {
40-
entity['type'].__name__: entity['type']
41-
for entity in query.column_descriptions
40+
col_desc['entity'].__name__: col_desc['entity']
41+
for col_desc in query.column_descriptions
4242
}

test/interface/test_filters.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import datetime
44

55
import pytest
6+
from sqlalchemy import func
67
from sqlalchemy_filters import apply_filters
78
from sqlalchemy_filters.exceptions import (
89
BadFilterFormat, FieldNotFound, BadQuery
@@ -240,6 +241,32 @@ def test_a_single_dict_can_be_supplied_as_filters(self, session):
240241
assert result[1].name == 'name_1'
241242

242243

244+
class TestApplyFilterOnFieldBasedQuery(TestFiltersMixin):
245+
246+
@pytest.mark.usefixtures('multiple_bars_inserted')
247+
def test_apply_filter_on_single_field_query(self, session):
248+
query = session.query(Bar.id)
249+
filters = [{'field': 'name', 'op': '==', 'value': 'name_1'}]
250+
251+
filtered_query = apply_filters(query, filters)
252+
result = filtered_query.all()
253+
254+
assert len(result) == 2
255+
assert result[0] == (1,)
256+
assert result[1] == (3,)
257+
258+
@pytest.mark.usefixtures('multiple_bars_inserted')
259+
def test_apply_filter_on_aggregate_query(self, session):
260+
query = session.query(func.count(Bar.id))
261+
filters = [{'field': 'name', 'op': '==', 'value': 'name_1'}]
262+
263+
filtered_query = apply_filters(query, filters)
264+
result = filtered_query.all()
265+
266+
assert len(result) == 1
267+
assert result[0] == (2,)
268+
269+
243270
class TestApplyEqualToFilter(TestFiltersMixin):
244271

245272
@pytest.mark.parametrize('operator', ['==', 'eq'])

test/interface/test_models.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
from sqlalchemy import func
12
from sqlalchemy_filters import get_query_models
2-
from test.models import Bar, Qux
3+
from test.models import Bar, Foo, Qux
34

45

56
class TestGetQueryModels(object):
@@ -31,3 +32,24 @@ def test_query_with_duplicated_models(self, session):
3132
entities = get_query_models(query)
3233

3334
assert {'Bar': Bar, 'Qux': Qux} == entities
35+
36+
def test_query_with_one_field(self, session):
37+
query = session.query(Foo.id)
38+
39+
entities = get_query_models(query)
40+
41+
assert {'Foo': Foo} == entities
42+
43+
def test_query_with_multiple_fields(self, session):
44+
query = session.query(Foo.id, Bar.id, Bar.name)
45+
46+
entities = get_query_models(query)
47+
48+
assert {'Foo': Foo, 'Bar': Bar} == entities
49+
50+
def test_query_with_aggregate_func(self, session):
51+
query = session.query(func.count(Foo.id))
52+
53+
entities = get_query_models(query)
54+
55+
assert {'Foo': Foo} == entities

0 commit comments

Comments
 (0)