Skip to content

Commit e1c0be4

Browse files
[BREAKING CHANGE]: Add new filter types and rename InFilter to LikeFilter
1 parent d64b2a8 commit e1c0be4

File tree

8 files changed

+143
-24
lines changed

8 files changed

+143
-24
lines changed

README.md

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pip install nocodb
1414
### Client configuration
1515
```python
1616
from nocodb.nocodb import NocoDBProject, APIToken, JWTAuthToken
17-
from nocodb.filters import InFilter, EqFilter
17+
from nocodb.filters import LikeFilter, EqFilter
1818
from nocodb.infra.requests_client import NocoDBRequestsClient
1919

2020

@@ -98,7 +98,7 @@ table_rows = client.table_row_list(project, table_name, params={'offset': 100})
9898
# Filter the query
9999
# Currently only one filter at a time is allowed. I don't know how to join
100100
# multiple conditions in nocodb dsl. If you know how please let me know :).
101-
table_rows = client.table_row_list(project, table_name, InFilter("name", "sam"))
101+
table_rows = client.table_row_list(project, table_name, LikeFilter("name", "%sam%"))
102102
table_rows = client.table_row_list(project, table_name, filter_obj=EqFilter("Id", 100))
103103

104104
# Filter and count rows
@@ -114,22 +114,79 @@ row = client.table_row_detail(project, table_name, row_id)
114114
# Create a new row
115115
row_info = {
116116
"name": "my thoughts",
117-
"content": "i'm going to buy samuel a beer because i love this module",
117+
"content": "i'm going to buy samuel a beer 🍻 because I 💚 this module",
118118
"mood": ":)"
119119
}
120120
client.table_row_create(project, table_name, row_info)
121121

122122
# Update a row
123123
row_id = 2
124124
row_info = {
125-
"content": "i'm going to buy samuel a new car because i love this module",
125+
"content": "i'm going to buy samuel a new car 🚙 because I 💚 this module",
126126
}
127127
client.table_row_update(project, table_name, row_id, row_info)
128128

129129
# Delete a row (only if you've already bought me a beer)
130130
client.table_row_delete(project, table_name, row_id)
131131
```
132132

133+
### Available filters
134+
135+
- EqFilter
136+
- EqualFilter (Alias of EqFilter)
137+
- NotEqualFilter
138+
- GreaterThanFilter
139+
- GreaterOrEqualFilter
140+
- LessThanFilter
141+
- LessOrEqualFilter
142+
- LikeFilter
143+
144+
### Using custom filters
145+
146+
Nocodb is evolving and new operators are comming with each release.
147+
148+
Most of the basic operations are inside this package but you could need some new
149+
feature that could not be added yet.
150+
For those filters you can build your own.
151+
152+
Example for basic filters:
153+
154+
```python
155+
from nocodb.filters.factory import basic_filter_class_factory
156+
157+
BasicFilter = basic_filter_class_factory('=')
158+
table_rows = client.table_row_list(project, table_name, BasicFilter('age', '16'))
159+
160+
```
161+
162+
You can find the updated list of all the available nocodb operators [here](https://docs.nocodb.com/developer-resources/rest-apis/#comparison-operators).
163+
164+
In some cases you might want to write your own filter string as described in the previous link.
165+
For that cases you can use the less-semmantic RawFilter.
166+
167+
```python
168+
from nocodb.filters.raw_filter import RawFilter
169+
170+
table_rows = client.table_row_list(project, table_name, RawFilter('(birthday,eq,exactDate,2023-06-01)'))
171+
```
172+
173+
In some cases we might want to have a file with some custom raw filters already defined by us.
174+
We can easily create custom raw filter classes using `raw_template_filter_class_factory`.
175+
176+
```python
177+
from nocodb.filters.factory import raw_template_filter_class_factory
178+
179+
BirthdayDateFilter = raw_template_filter_class_factory('(birthday,eq,exactDate,{})')
180+
ExactDateEqFilter = raw_template_filter_class_factory('({},eq,exactDate,{})')
181+
ExactDateOpFilter = raw_template_filter_class_factory('({},{op},exactDate,{})')
182+
183+
table_rows = client.table_row_list(project, table_name, BirthdayDateFilter('2023-06-01'))
184+
table_rows = client.table_row_list(project, table_name, ExactDateEqFilter('column', '2023-06-01'))
185+
table_rows = client.table_row_list(project, table_name, ExactDateOpFilter('column', '2023-06-01', op='eq'))
186+
```
187+
188+
Credits to @MitPitt for asking this feature.
189+
133190
## Author notes
134191

135192
I created this package to bootstrap some personal projects and I hope it

nocodb/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.0.1"
1+
__version__ = "2.0.0"

nocodb/filters.py

Lines changed: 0 additions & 19 deletions
This file was deleted.

nocodb/filters/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from ..nocodb import WhereFilter
2+
from .factory import basic_filter_class_factory
3+
4+
5+
EqFilter = basic_filter_class_factory('eq')
6+
EqualFilter = EqFilter
7+
NotEqualFilter = basic_filter_class_factory('neq')
8+
GreaterThanFilter = basic_filter_class_factory('gt')
9+
GreaterOrEqualFilter = basic_filter_class_factory('ge')
10+
LessThanFilter = basic_filter_class_factory('lt')
11+
LessOrEqualFilter = basic_filter_class_factory('le')
12+
LikeFilter = basic_filter_class_factory('like')

nocodb/filters/factory.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from ..nocodb import WhereFilter
2+
3+
from .raw_filter import RawTemplateFilter
4+
5+
6+
def basic_filter_class_factory(filter_name: str):
7+
return raw_template_filter_class_factory('({},' + filter_name + ',{})')
8+
9+
def raw_template_filter_class_factory(template: str):
10+
class WrappedFilter(WhereFilter):
11+
def __init__(self, *args, **kwargs):
12+
self.__filter = RawTemplateFilter(template, *args, **kwargs)
13+
def get_where(self) -> str:
14+
return self.__filter.get_where()
15+
return WrappedFilter

nocodb/filters/factory_test.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from .factory import basic_filter_class_factory, raw_template_filter_class_factory
2+
3+
4+
def test_basic_filter_class_factory():
5+
FilterClass = basic_filter_class_factory('eq')
6+
assert FilterClass('column', 'value').get_where() == '(column,eq,value)'
7+
8+
9+
def test_raw_template_filter_class_factory():
10+
FilterClassWithoutParams = raw_template_filter_class_factory('()')
11+
FilterClassWithParams = raw_template_filter_class_factory('({},{},{})')
12+
FilterClassWithKwargs = raw_template_filter_class_factory('({},{op},{})')
13+
assert FilterClassWithoutParams().get_where() == '()'
14+
assert FilterClassWithParams('1', '2','3').get_where() == '(1,2,3)'
15+
assert FilterClassWithKwargs('1', '2', op='eq').get_where() == '(1,eq,2)'

nocodb/filters/filters_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import pytest
2+
3+
from .. import filters
4+
5+
from ..nocodb import WhereFilter
6+
7+
8+
@pytest.mark.parametrize('filter_class, expected_operator', [
9+
(filters.EqFilter, 'eq'),
10+
(filters.EqualFilter, 'eq'),
11+
(filters.NotEqualFilter, 'neq'),
12+
(filters.GreaterOrEqualFilter, 'ge'),
13+
(filters.GreaterThanFilter, 'gt'),
14+
(filters.LessThanFilter, 'lt'),
15+
(filters.LessOrEqualFilter, 'le'),
16+
(filters.LikeFilter, 'like')
17+
])
18+
def test_basic_filters_are_correctly_created(filter_class: WhereFilter, expected_operator: str):
19+
test_filter = filter_class('column', 'value')
20+
assert test_filter.get_where() == f'(column,{expected_operator},value)'

nocodb/filters/raw_filter.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from ..nocodb import WhereFilter
2+
3+
4+
class RawFilter(WhereFilter):
5+
def __init__(self, raw: str):
6+
self.__raw = raw
7+
8+
def get_where(self) -> str:
9+
return self.__raw
10+
11+
12+
class RawTemplateFilter(WhereFilter):
13+
def __init__(self, template: str, *args, **kwargs):
14+
self.__template = template
15+
self.__template_values = args
16+
self.__template_kvalues = kwargs
17+
18+
def get_where(self) -> str:
19+
return self.__template.format(*self.__template_values, **self.__template_kvalues)

0 commit comments

Comments
 (0)