Skip to content
Open
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
26 changes: 13 additions & 13 deletions src/postgrest/src/postgrest/_async/request_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ def retry(self, enabled: bool) -> Self:
self.request.retry_enabled = enabled
return self

def single(self) -> AsyncSingleRequestBuilder:
"""Specify that the query will only return a single row in response.

.. caution::
The API will raise an error if the query returned more than one row.
"""
self.request.headers["Accept"] = "application/vnd.pgrst.object+json"
return AsyncSingleRequestBuilder(self.request)

def maybe_single(self) -> AsyncMaybeSingleRequestBuilder:
"""Retrieves at most one row from the result. Result must be at most one row (e.g. using `eq` on a UNIQUE column), otherwise this will result in an error."""
return AsyncMaybeSingleRequestBuilder(self.request)

async def execute(self) -> APIResponse:
"""Execute the query.

Expand Down Expand Up @@ -205,19 +218,6 @@ def __init__(self, request: ReqConfig) -> None:
BaseSelectRequestBuilder.__init__(self, request)
AsyncQueryRequestBuilder.__init__(self, request)

def single(self) -> AsyncSingleRequestBuilder:
"""Specify that the query will only return a single row in response.

.. caution::
The API will raise an error if the query returned more than one row.
"""
self.request.headers["Accept"] = "application/vnd.pgrst.object+json"
return AsyncSingleRequestBuilder(self.request)

def maybe_single(self) -> AsyncMaybeSingleRequestBuilder:
"""Retrieves at most one row from the result. Result must be at most one row (e.g. using `eq` on a UNIQUE column), otherwise this will result in an error."""
return AsyncMaybeSingleRequestBuilder(self.request)

def text_search(
self, column: str, query: str, options: dict[str, Any] = {}
) -> AsyncQueryRequestBuilder:
Expand Down
26 changes: 13 additions & 13 deletions src/postgrest/src/postgrest/_sync/request_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ def retry(self, enabled: bool) -> Self:
self.request.retry_enabled = enabled
return self

def single(self) -> SyncSingleRequestBuilder:
"""Specify that the query will only return a single row in response.

.. caution::
The API will raise an error if the query returned more than one row.
"""
self.request.headers["Accept"] = "application/vnd.pgrst.object+json"
return SyncSingleRequestBuilder(self.request)

def maybe_single(self) -> SyncMaybeSingleRequestBuilder:
"""Retrieves at most one row from the result. Result must be at most one row (e.g. using `eq` on a UNIQUE column), otherwise this will result in an error."""
return SyncMaybeSingleRequestBuilder(self.request)

def execute(self) -> APIResponse:
"""Execute the query.

Expand Down Expand Up @@ -205,19 +218,6 @@ def __init__(self, request: ReqConfig) -> None:
BaseSelectRequestBuilder.__init__(self, request)
SyncQueryRequestBuilder.__init__(self, request)

def single(self) -> SyncSingleRequestBuilder:
"""Specify that the query will only return a single row in response.

.. caution::
The API will raise an error if the query returned more than one row.
"""
self.request.headers["Accept"] = "application/vnd.pgrst.object+json"
return SyncSingleRequestBuilder(self.request)

def maybe_single(self) -> SyncMaybeSingleRequestBuilder:
"""Retrieves at most one row from the result. Result must be at most one row (e.g. using `eq` on a UNIQUE column), otherwise this will result in an error."""
return SyncMaybeSingleRequestBuilder(self.request)

def text_search(
self, column: str, query: str, options: dict[str, Any] = {}
) -> SyncQueryRequestBuilder:
Expand Down
22 changes: 21 additions & 1 deletion src/postgrest/tests/_async/test_query_request_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
from yarl import URL

from postgrest import AsyncQueryRequestBuilder
from postgrest._async.request_builder import RequestConfig
from postgrest._async.request_builder import (
AsyncMaybeSingleRequestBuilder,
AsyncSingleRequestBuilder,
RequestConfig,
)


@pytest.fixture
Expand All @@ -25,3 +29,19 @@ def test_constructor(query_request_builder: AsyncQueryRequestBuilder):
assert len(builder.request.params) == 0
assert builder.request.http_method == "GET"
assert builder.request.json is None


def test_select_single(query_request_builder: AsyncQueryRequestBuilder):
# insert()/upsert() return an AsyncQueryRequestBuilder, so single() must be
# reachable after select() to match the JS client's
# insert(...).select().single() chain. See GH-1553.
builder = query_request_builder.select("*").single()

assert isinstance(builder, AsyncSingleRequestBuilder)
assert builder.request.headers["Accept"] == "application/vnd.pgrst.object+json"


def test_select_maybe_single(query_request_builder: AsyncQueryRequestBuilder):
builder = query_request_builder.select("*").maybe_single()

assert isinstance(builder, AsyncMaybeSingleRequestBuilder)
22 changes: 21 additions & 1 deletion src/postgrest/tests/_sync/test_query_request_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
from yarl import URL

from postgrest import SyncQueryRequestBuilder
from postgrest._sync.request_builder import RequestConfig
from postgrest._sync.request_builder import (
RequestConfig,
SyncMaybeSingleRequestBuilder,
SyncSingleRequestBuilder,
)


@pytest.fixture
Expand All @@ -25,3 +29,19 @@ def test_constructor(query_request_builder: SyncQueryRequestBuilder):
assert len(builder.request.params) == 0
assert builder.request.http_method == "GET"
assert builder.request.json is None


def test_select_single(query_request_builder: SyncQueryRequestBuilder):
# insert()/upsert() return a SyncQueryRequestBuilder, so single() must be
# reachable after select() to match the JS client's
# insert(...).select().single() chain. See GH-1553.
builder = query_request_builder.select("*").single()

assert isinstance(builder, SyncSingleRequestBuilder)
assert builder.request.headers["Accept"] == "application/vnd.pgrst.object+json"


def test_select_maybe_single(query_request_builder: SyncQueryRequestBuilder):
builder = query_request_builder.select("*").maybe_single()

assert isinstance(builder, SyncMaybeSingleRequestBuilder)