Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/postgrest/src/postgrest/_async/request_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
from ..utils import model_validate_json

ReqConfig = RequestConfig[AsyncClient]
_MAYBE_SINGLE_NO_ROWS_DETAILS = "The result contains 0 rows"


def _is_maybe_single_no_rows_error(error: APIError) -> bool:
return str(error.code) == "204" or (
error.details is not None and _MAYBE_SINGLE_NO_ROWS_DETAILS in error.details
)


class AsyncQueryRequestBuilder:
Expand Down Expand Up @@ -109,8 +116,8 @@ async def execute(self) -> Optional[SingleAPIResponse]:
try:
r = await AsyncSingleRequestBuilder(self.request).execute()
except APIError as e:
if e.details and "The result contains 0 rows" in e.details:
return None
if _is_maybe_single_no_rows_error(e):
return SingleAPIResponse(data=None)
if not r:
raise APIError(
{
Expand All @@ -120,6 +127,8 @@ async def execute(self) -> Optional[SingleAPIResponse]:
"details": "Postgrest couldn't retrieve response, please check traceback of the code. Please create an issue in `supabase-community/postgrest-py` if needed.",
}
)
if r.data == []:
return SingleAPIResponse(data=None, count=r.count)
return r


Expand Down
13 changes: 11 additions & 2 deletions src/postgrest/src/postgrest/_sync/request_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
from ..utils import model_validate_json

ReqConfig = RequestConfig[Client]
_MAYBE_SINGLE_NO_ROWS_DETAILS = "The result contains 0 rows"


def _is_maybe_single_no_rows_error(error: APIError) -> bool:
return str(error.code) == "204" or (
error.details is not None and _MAYBE_SINGLE_NO_ROWS_DETAILS in error.details
)


class SyncQueryRequestBuilder:
Expand Down Expand Up @@ -109,8 +116,8 @@ def execute(self) -> Optional[SingleAPIResponse]:
try:
r = SyncSingleRequestBuilder(self.request).execute()
except APIError as e:
if e.details and "The result contains 0 rows" in e.details:
return None
if _is_maybe_single_no_rows_error(e):
return SingleAPIResponse(data=None)
if not r:
raise APIError(
{
Expand All @@ -120,6 +127,8 @@ def execute(self) -> Optional[SingleAPIResponse]:
"details": "Postgrest couldn't retrieve response, please check traceback of the code. Please create an issue in `supabase-community/postgrest-py` if needed.",
}
)
if r.data == []:
return SingleAPIResponse(data=None, count=r.count)
return r


Expand Down
48 changes: 48 additions & 0 deletions src/postgrest/tests/_async/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,54 @@ async def test_response_maybe_single(postgrest_client: AsyncPostgrestClient):
assert "code" in exc_response and int(exc_response["code"]) == 204


@pytest.mark.asyncio
async def test_maybe_single_returns_none_on_no_rows_204(
postgrest_client: AsyncPostgrestClient,
):
with patch(
"httpx._client.AsyncClient.request",
return_value=Response(
status_code=204,
request=Request(method="GET", url="http://example.com"),
),
):
response = await (
postgrest_client.from_("test")
.select("a", "b")
.eq("c", "d")
.maybe_single()
.execute()
)

assert response is not None
assert response.data is None


@pytest.mark.asyncio
async def test_single_raises_on_no_rows(postgrest_client: AsyncPostgrestClient):
with patch(
"httpx._client.AsyncClient.request",
return_value=Response(
status_code=406,
json={
"message": "JSON object requested, multiple (or no) rows returned",
"code": "PGRST116",
"hint": None,
"details": "The result contains 0 rows",
},
request=Request(method="GET", url="http://example.com"),
),
):
with pytest.raises(APIError):
await (
postgrest_client.from_("test")
.select("a", "b")
.eq("c", "d")
.single()
.execute()
)


# https://github.com/supabase/postgrest-py/issues/595
@pytest.mark.asyncio
async def test_response_client_invalid_response_but_valid_json(
Expand Down
46 changes: 46 additions & 0 deletions src/postgrest/tests/_sync/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,52 @@ def test_response_maybe_single(postgrest_client: SyncPostgrestClient):
assert "code" in exc_response and int(exc_response["code"]) == 204


def test_maybe_single_returns_none_on_no_rows_204(
postgrest_client: SyncPostgrestClient,
):
with patch(
"httpx._client.Client.request",
return_value=Response(
status_code=204,
request=Request(method="GET", url="http://example.com"),
),
):
response = (
postgrest_client.from_("test")
.select("a", "b")
.eq("c", "d")
.maybe_single()
.execute()
)

assert response is not None
assert response.data is None


def test_single_raises_on_no_rows(postgrest_client: SyncPostgrestClient):
with patch(
"httpx._client.Client.request",
return_value=Response(
status_code=406,
json={
"message": "JSON object requested, multiple (or no) rows returned",
"code": "PGRST116",
"hint": None,
"details": "The result contains 0 rows",
},
request=Request(method="GET", url="http://example.com"),
),
):
with pytest.raises(APIError):
(
postgrest_client.from_("test")
.select("a", "b")
.eq("c", "d")
.single()
.execute()
)


# https://github.com/supabase/postgrest-py/issues/595


Expand Down