Add Postgres table adapter with TableRepositoryInterface.
PR Title Check / check-title (pull_request) Successful in 7s
Code Quality Pipeline / code-quality (pull_request) Failing after 19s
Test Python Package / unit-tests (pull_request) Successful in 47s
Test Python Package / integration-tests (pull_request) Successful in 44s
Test Python Package / coverage-report (pull_request) Successful in 11s
PR Title Check / check-title (pull_request) Successful in 7s
Code Quality Pipeline / code-quality (pull_request) Failing after 19s
Test Python Package / unit-tests (pull_request) Successful in 47s
Test Python Package / integration-tests (pull_request) Successful in 44s
Test Python Package / coverage-report (pull_request) Successful in 11s
Introduce PostgresAdapter for dict-based row CRUD via psycopg3, including config, lazy exports, unit/integration tests with testcontainers, and an example UserTableRepository. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
co-authored by
Cursor
parent
f28d3c4844
commit
dc6f8a3e89
@@ -8,10 +8,14 @@ from .json_repository_interface import (
|
||||
from .object_repository_interface import (
|
||||
ObjectRepositoryInterface as ObjectRepositoryInterface,
|
||||
)
|
||||
from .table_repository_interface import (
|
||||
TableRepositoryInterface as TableRepositoryInterface,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"ConnectionAwareInterface",
|
||||
"ContextAwareInterface",
|
||||
"JsonRepositoryInterface",
|
||||
"ObjectRepositoryInterface",
|
||||
"TableRepositoryInterface",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
"""Definition of TableRepositoryInterface protocol."""
|
||||
|
||||
from abc import abstractmethod
|
||||
from typing import Any, Protocol, runtime_checkable
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class TableRepositoryInterface(Protocol):
|
||||
"""Interface that defines relational table CRUD methods."""
|
||||
|
||||
@abstractmethod
|
||||
def fetch_one(self, pk: Any) -> dict[str, Any] | None:
|
||||
"""Fetch a single row by primary key.
|
||||
|
||||
Returns ``None`` when no row matches. Use ``value is not None`` to test
|
||||
existence; avoid truthiness checks.
|
||||
"""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def fetch_all(self, *, limit: int | None = None) -> list[dict[str, Any]]:
|
||||
"""Fetch all rows from the configured table.
|
||||
|
||||
Returns an empty list when the table has no rows.
|
||||
"""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def upsert(self, row: dict[str, Any]) -> None:
|
||||
"""Insert or update a row by primary key.
|
||||
|
||||
``row`` must include the configured primary key column. Raises
|
||||
``ValueError`` for a non-dict row or a missing primary key.
|
||||
"""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def delete(self, pk: Any) -> None:
|
||||
"""Delete a row by primary key.
|
||||
|
||||
Idempotent: no error when the row is already absent.
|
||||
"""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def execute(
|
||||
self,
|
||||
sql: str,
|
||||
params: tuple[Any, ...] = (),
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Run a read SQL statement and return rows as dicts.
|
||||
|
||||
Escape hatch for joins, filters, and other queries in subclasses.
|
||||
"""
|
||||
...
|
||||
Reference in New Issue
Block a user