Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: resolve group_by config values for SPARQL binding aliases #162

Merged
merged 2 commits into from
Dec 5, 2024
Merged
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
17 changes: 15 additions & 2 deletions rdfproxy/utils/sparql_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from SPARQLWrapper import QueryResult, SPARQLWrapper
from rdfproxy.utils._exceptions import QueryConstructionException
from rdfproxy.utils._types import ItemsQueryConstructor, _TModelInstance
from rdfproxy.utils._types import ItemsQueryConstructor, SPARQLBinding, _TModelInstance


def construct_ungrouped_pagination_query(query: str, limit: int, offset: int) -> str:
Expand Down Expand Up @@ -79,6 +79,12 @@ def get_items_query_constructor(

if (group_by_value := model.model_config.get("group_by", None)) is None:
return construct_ungrouped_pagination_query

elif meta := model.model_fields[group_by_value].metadata:
group_by_value = next(
filter(lambda x: isinstance(x, SPARQLBinding), meta), group_by_value
)

return partial(construct_grouped_pagination_query, group_by_value=group_by_value)


Expand All @@ -96,7 +102,14 @@ def construct_count_query(query: str, model: type[_TModelInstance]) -> str:
"""Construct a generic count query from a SELECT query."""
try:
group_by: str = model.model_config["group_by"]
count_query = construct_grouped_count_query(query, group_by)
group_by_binding = next(
filter(
lambda x: isinstance(x, SPARQLBinding),
model.model_fields[group_by].metadata,
),
group_by,
)
count_query = construct_grouped_count_query(query, group_by_binding)
except KeyError:
count_query = replace_query_select_clause(query, "select (count(*) as ?cnt)")

Expand Down
2 changes: 2 additions & 0 deletions tests/data/models/dummy_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ class Dummy(BaseModel):

class GroupedDummy(BaseModel):
model_config = ConfigDict(group_by="x")

x: int
92 changes: 84 additions & 8 deletions tests/tests_adapter/test_adapter_grouped_pagination.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
"""Basic tests for rdfproxy.SPARQLModelAdapter pagination with grouped models."""

from typing import Any, NamedTuple
from typing import Annotated, Any, NamedTuple

import pytest

from pydantic import BaseModel, ConfigDict
from rdfproxy import Page, QueryParameters, SPARQLModelAdapter
from rdfproxy import Page, QueryParameters, SPARQLBinding, SPARQLModelAdapter


binding_query = """
select ?parentBinding ?child ?name
where {
values (?parentBinding ?child ?name) {
('x' 'c' 'foo')
('y' 'd' UNDEF)
('y' 'e' UNDEF)
('z' UNDEF UNDEF)
}
}
"""

query = """
select ?parent ?child ?name
where {
Expand All @@ -25,14 +37,27 @@ class Child(BaseModel):
name: str | None = None


class BindingParent(BaseModel):
model_config = ConfigDict(group_by="parent")

parent: Annotated[str, SPARQLBinding("parentBinding")]
children: list[Child]


class Parent(BaseModel):
model_config = ConfigDict(group_by="parent")

parent: str
children: list[Child]


parent_adapter = SPARQLModelAdapter(
binding_adapter = SPARQLModelAdapter(
target="https://graphdb.r11.eu/repositories/RELEVEN",
query=binding_query,
model=BindingParent,
)

adapter = SPARQLModelAdapter(
target="https://graphdb.r11.eu/repositories/RELEVEN",
query=query,
model=Parent,
Expand All @@ -47,7 +72,58 @@ class AdapterParameter(NamedTuple):

adapter_parameters = [
AdapterParameter(
adapter=parent_adapter,
adapter=binding_adapter,
query_parameters={"page": 1, "size": 2},
expected=Page[BindingParent](
items=[
{"parent": "x", "children": [{"name": "foo"}]},
{"parent": "y", "children": []},
],
page=1,
size=2,
total=3,
pages=2,
),
),
AdapterParameter(
adapter=binding_adapter,
query_parameters={"page": 2, "size": 2},
expected=Page[BindingParent](
items=[{"parent": "z", "children": []}],
page=2,
size=2,
total=3,
pages=2,
),
),
AdapterParameter(
adapter=binding_adapter,
query_parameters={"page": 1, "size": 1},
expected=Page[BindingParent](
items=[{"parent": "x", "children": [{"name": "foo"}]}],
page=1,
size=1,
total=3,
pages=3,
),
),
AdapterParameter(
adapter=binding_adapter,
query_parameters={"page": 2, "size": 1},
expected=Page[BindingParent](
items=[{"parent": "y", "children": []}], page=2, size=1, total=3, pages=3
),
),
AdapterParameter(
adapter=binding_adapter,
query_parameters={"page": 3, "size": 1},
expected=Page[BindingParent](
items=[{"parent": "z", "children": []}], page=3, size=1, total=3, pages=3
),
),
#
AdapterParameter(
adapter=adapter,
query_parameters={"page": 1, "size": 2},
expected=Page[Parent](
items=[
Expand All @@ -61,7 +137,7 @@ class AdapterParameter(NamedTuple):
),
),
AdapterParameter(
adapter=parent_adapter,
adapter=adapter,
query_parameters={"page": 2, "size": 2},
expected=Page[Parent](
items=[{"parent": "z", "children": []}],
Expand All @@ -72,7 +148,7 @@ class AdapterParameter(NamedTuple):
),
),
AdapterParameter(
adapter=parent_adapter,
adapter=adapter,
query_parameters={"page": 1, "size": 1},
expected=Page[Parent](
items=[{"parent": "x", "children": [{"name": "foo"}]}],
Expand All @@ -83,14 +159,14 @@ class AdapterParameter(NamedTuple):
),
),
AdapterParameter(
adapter=parent_adapter,
adapter=adapter,
query_parameters={"page": 2, "size": 1},
expected=Page[Parent](
items=[{"parent": "y", "children": []}], page=2, size=1, total=3, pages=3
),
),
AdapterParameter(
adapter=parent_adapter,
adapter=adapter,
query_parameters={"page": 3, "size": 1},
expected=Page[Parent](
items=[{"parent": "z", "children": []}], page=3, size=1, total=3, pages=3
Expand Down
Loading