Skip to content

Commit e302009

Browse files
feat: add or filter along with tests (#355)
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
1 parent 83ca3cd commit e302009

12 files changed

+808
-8
lines changed

Makefile

+8-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ clean_infra:
2222
docker-compose down --remove-orphans &&\
2323
docker system prune -a --volumes -f
2424

25-
run_tests: tests
25+
stop_infra:
26+
cd infra &&\
27+
docker-compose down --remove-orphans
28+
29+
run_tests: run_infra sleep tests
2630

2731
run_unasync:
2832
poetry run unasync postgrest tests
@@ -31,3 +35,6 @@ build_sync: run_unasync remove_pytest_asyncio_from_sync
3135

3236
remove_pytest_asyncio_from_sync:
3337
sed -i 's/@pytest.mark.asyncio//g' tests/_sync/test_client.py
38+
39+
sleep:
40+
sleep 5

infra/docker-compose.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ services:
2020
POSTGRES_USER: app_user
2121
POSTGRES_PASSWORD: password
2222
# Uncomment this if you want to persist the data. Create your boostrap SQL file in the project root
23-
# volumes:
24-
# - "./pgdata:/var/lib/postgresql/data"
25-
# - "./init.sql:/docker-entrypoint-initdb.d/init.sql"
23+
volumes:
24+
# - "./pgdata:/var/lib/postgresql/data"
25+
- "./init.sql:/docker-entrypoint-initdb.d/init.sql"

infra/init.sql

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
CREATE TABLE public.countries (
2+
id int8 PRIMARY KEY,
3+
iso CHAR (2) NOT NULL,
4+
country_name VARCHAR (80) NOT NULL,
5+
nicename VARCHAR (80) NOT NULL,
6+
iso3 CHAR (3) DEFAULT NULL,
7+
numcode SMALLINT DEFAULT NULL,
8+
phonecode INT NOT NULL
9+
);
10+
11+
INSERT INTO public.countries (id, iso, country_name, nicename, iso3, numcode, phonecode) VALUES
12+
(1, 'AF', 'AFGHANISTAN', 'Afghanistan', 'AFG', 4, 93),
13+
(2, 'AL', 'ALBANIA', 'Albania', 'ALB', 8, 355),
14+
(3, 'DZ', 'ALGERIA', 'Algeria', 'DZA', 12, 213),
15+
(4, 'AQ', 'ANTARCTICA', 'Antarctica', NULL, NULL, 0),
16+
(5, 'CR', 'COSTA RICA', 'Costa Rica', 'CRI', 188, 506),
17+
(6, 'ES', 'SPAIN', 'Spain', 'ESP', 724, 34),
18+
(7, 'TH', 'THAILAND', 'Thailand', 'THA', 764, 66),
19+
(8, 'TG', 'TOGO', 'Togo', 'TGO', 768, 228),
20+
(9, 'TT', 'TRINIDAD AND TOBAGO', 'Trinidad and Tobago', 'TTO', 780, 1868),
21+
(10, 'GB', 'UNITED KINGDOM', 'United Kingdom', 'GBR', 826, 44),
22+
(11, 'US', 'UNITED STATES', 'United States', 'USA', 840, 1),
23+
(12, 'ZW', 'ZIMBABWE', 'Zimbabwe', 'ZWE', 716, 263);
24+
25+
create table public.cities (
26+
id int8 primary key,
27+
country_id int8 not null references public.countries,
28+
name text
29+
);
30+
31+
insert into public.cities (id, name, country_id) values
32+
(1, 'London', 10),
33+
(2, 'Manchester', 10),
34+
(3, 'Liverpool', 10),
35+
(4, 'Bristol', 10),
36+
(5, 'Miami', 11),
37+
(6, 'Huston', 11),
38+
(7, 'Atlanta', 11);
39+
40+
create table public.users (
41+
id int8 primary key,
42+
name text,
43+
address jsonb
44+
);
45+
46+
insert into public.users (id, name, address) values
47+
(1, 'Michael', '{ "postcode": 90210, "street": "Melrose Place" }'),
48+
(2, 'Jane', '{}');
49+
50+
create table public.reservations (
51+
id int8 primary key,
52+
room_name text,
53+
during tsrange
54+
);
55+
56+
insert into public.reservations (id, room_name, during) values
57+
(1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'),
58+
(2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)');
59+
60+
61+
create table public.issues (
62+
id int8 primary key,
63+
title text,
64+
tags text[]
65+
);
66+
67+
insert into public.issues (id, title, tags) values
68+
(1, 'Cache invalidation is not working', array['is:open', 'severity:high', 'priority:low']),
69+
(2, 'Use better names', array['is:open', 'severity:low', 'priority:medium']),
70+
(3, 'Add missing postgrest filters', array['is:open', 'severity:low', 'priority:high']),
71+
(4, 'Add alias to filters', array['is:closed', 'severity:low', 'priority:medium']);

poetry.lock

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

postgrest/base_request_builder.py

+11
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,17 @@ def ilike(self: Self, column: str, pattern: str) -> Self:
330330
"""
331331
return self.filter(column, Filters.ILIKE, pattern)
332332

333+
def or_(self: Self, filters: str, reference_table: Union[str, None] = None) -> Self:
334+
"""An 'or' filter
335+
336+
Args:
337+
filters: The filters to use, following PostgREST syntax
338+
reference_table: Set this to filter on referenced tables instead of the parent table
339+
"""
340+
key = f"{sanitize_param(reference_table)}.or" if reference_table else "or"
341+
self.params = self.params.add(key, f"({filters})")
342+
return self
343+
333344
def fts(self: Self, column: str, query: Any) -> Self:
334345
return self.filter(column, Filters.FTS, query)
335346

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "postgrest"
33
version = "0.13.2"
44
description = "PostgREST client for Python. This library provides an ORM interface to PostgREST."
5-
authors = ["Lương Quang Mạnh <[email protected]>", "Joel Lee <[email protected]>", "Anand", "Oliver Rice"]
5+
authors = ["Lương Quang Mạnh <[email protected]>", "Joel Lee <[email protected]>", "Anand", "Oliver Rice", "Andrew Smith <[email protected]>"]
66
homepage = "https://github.com/supabase-community/postgrest-py"
77
repository = "https://github.com/supabase-community/postgrest-py"
88
documentation = "https://postgrest-py.rtfd.io"

tests/_async/client.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from postgrest import AsyncPostgrestClient
2+
3+
REST_URL = "http://127.0.0.1:3000"
4+
5+
6+
def rest_client():
7+
return AsyncPostgrestClient(
8+
base_url=REST_URL,
9+
)

tests/_async/test_filter_request_builder.py

+15
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,18 @@ def test_in_(filter_request_builder):
200200
builder = filter_request_builder.in_("x", ["a", "b"])
201201

202202
assert str(builder.params) == "x=in.%28a%2Cb%29"
203+
204+
205+
def test_or_(filter_request_builder):
206+
builder = filter_request_builder.or_("x.eq.1")
207+
208+
assert str(builder.params) == "or=%28x.eq.1%29"
209+
210+
211+
def test_or_in_contain(filter_request_builder):
212+
builder = filter_request_builder.or_("id.in.(5,6,7), arraycol.cs.{'a','b'}")
213+
214+
assert (
215+
str(builder.params)
216+
== "or=%28id.in.%285%2C6%2C7%29%2C%20arraycol.cs.%7B%27a%27%2C%27b%27%7D%29"
217+
)

0 commit comments

Comments
 (0)