Skip to content

Commit 66477dd

Browse files
authored
fix: order using foreign table (#581)
1 parent c787410 commit 66477dd

6 files changed

+66
-23
lines changed

infra/init.sql

+21
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,24 @@ create or replace function public.list_stored_countries()
7676
as $function$
7777
select * from countries;
7878
$function$;
79+
80+
81+
create table
82+
orchestral_sections (id int8 primary key, name text);
83+
create table
84+
instruments (
85+
id int8 primary key,
86+
section_id int8 not null references orchestral_sections,
87+
name text
88+
);
89+
90+
insert into
91+
orchestral_sections (id, name)
92+
values
93+
(1, 'strings'),
94+
(2, 'woodwinds');
95+
insert into
96+
instruments (id, section_id, name)
97+
values
98+
(1, 1, 'harp'),
99+
(2, 1, 'violin');

postgrest/base_request_builder.py

+13-15
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ def order(
566566
column: str,
567567
*,
568568
desc: bool = False,
569-
nullsfirst: bool = False,
569+
nullsfirst: Optional[bool] = None,
570570
foreign_table: Optional[str] = None,
571571
) -> Self:
572572
"""Sort the returned rows in some specific order.
@@ -579,20 +579,18 @@ def order(
579579
.. versionchanged:: 0.10.3
580580
Allow ordering results for foreign tables with the foreign_table parameter.
581581
"""
582-
583-
new_order_parameter = (
584-
f"{foreign_table + '(' if foreign_table else ''}{column}{')' if foreign_table else ''}"
585-
f"{'.desc' if desc else ''}{'.nullsfirst' if nullsfirst else ''}"
586-
)
587-
588-
existing_order_parameter = self.params.get("order")
589-
if existing_order_parameter:
590-
self.params = self.params.remove("order")
591-
new_order_parameter = f"{existing_order_parameter},{new_order_parameter}"
592-
593-
self.params = self.params.add(
594-
"order",
595-
new_order_parameter,
582+
key = f"{foreign_table}.order" if foreign_table else "order"
583+
existing_order = self.params.get(key)
584+
585+
self.params = self.params.set(
586+
key,
587+
f"{existing_order + ',' if existing_order else ''}"
588+
+ f"{column}.{'desc' if desc else 'asc'}"
589+
+ (
590+
f".{'nullsfirst' if nullsfirst else 'nullslast'}"
591+
if nullsfirst is not None
592+
else ""
593+
),
596594
)
597595
return self
598596

tests/_async/test_filter_request_builder_integration.py

+15
Original file line numberDiff line numberDiff line change
@@ -498,3 +498,18 @@ async def test_order():
498498
{"country_name": "UNITED STATES", "iso": "US"},
499499
{"country_name": "UNITED KINGDOM", "iso": "GB"},
500500
]
501+
502+
503+
async def test_order_on_foreign_table():
504+
res = (
505+
await rest_client()
506+
.from_("orchestral_sections")
507+
.select("name, instruments(name)")
508+
.order("name", desc=True, foreign_table="instruments")
509+
.execute()
510+
)
511+
512+
assert res.data == [
513+
{"name": "strings", "instruments": [{"name": "violin"}, {"name": "harp"}]},
514+
{"name": "woodwinds", "instruments": []},
515+
]

tests/_async/test_request_builder.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,7 @@ def test_multiple_orders_on_foreign_table(self, request_builder: AsyncRequestBui
218218
.order("city_name", desc=True, foreign_table=foreign_table)
219219
.order("id", desc=True, foreign_table=foreign_table)
220220
)
221-
assert (
222-
str(builder.params)
223-
== "select=%2A&order=cities%28city_name%29.desc%2Ccities%28id%29.desc"
224-
)
221+
assert str(builder.params) == "select=%2A&cities.order=city_name.desc%2Cid.desc"
225222

226223

227224
class TestRange:

tests/_sync/test_filter_request_builder_integration.py

+15
Original file line numberDiff line numberDiff line change
@@ -491,3 +491,18 @@ def test_order():
491491
{"country_name": "UNITED STATES", "iso": "US"},
492492
{"country_name": "UNITED KINGDOM", "iso": "GB"},
493493
]
494+
495+
496+
def test_order_on_foreign_table():
497+
res = (
498+
rest_client()
499+
.from_("orchestral_sections")
500+
.select("name, instruments(name)")
501+
.order("name", desc=True, foreign_table="instruments")
502+
.execute()
503+
)
504+
505+
assert res.data == [
506+
{"name": "strings", "instruments": [{"name": "violin"}, {"name": "harp"}]},
507+
{"name": "woodwinds", "instruments": []},
508+
]

tests/_sync/test_request_builder.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,7 @@ def test_multiple_orders_on_foreign_table(self, request_builder: SyncRequestBuil
218218
.order("city_name", desc=True, foreign_table=foreign_table)
219219
.order("id", desc=True, foreign_table=foreign_table)
220220
)
221-
assert (
222-
str(builder.params)
223-
== "select=%2A&order=cities%28city_name%29.desc%2Ccities%28id%29.desc"
224-
)
221+
assert str(builder.params) == "select=%2A&cities.order=city_name.desc%2Cid.desc"
225222

226223

227224
class TestRange:

0 commit comments

Comments
 (0)