feat(api): ajoute l'opérateur de filtre differs (IS DISTINCT FROM) (#78)
Implémente l'opérateur de filtre `differs` qui génère un fragment SQL `IS DISTINCT FROM` pour exclure des valeurs en tenant compte des NULL. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ OPERATORS = {
|
|||||||
"exact",
|
"exact",
|
||||||
"contains",
|
"contains",
|
||||||
"notcontains",
|
"notcontains",
|
||||||
|
"differs",
|
||||||
"less",
|
"less",
|
||||||
"greater",
|
"greater",
|
||||||
"strictly_less",
|
"strictly_less",
|
||||||
@@ -132,6 +133,9 @@ def build_where(
|
|||||||
elif op == "notcontains":
|
elif op == "notcontains":
|
||||||
where_parts.append(f'"{col}" NOT LIKE ?')
|
where_parts.append(f'"{col}" NOT LIKE ?')
|
||||||
params.append(f"%{v}%")
|
params.append(f"%{v}%")
|
||||||
|
elif op == "differs":
|
||||||
|
where_parts.append(f'"{col}" IS DISTINCT FROM ?')
|
||||||
|
params.append(v)
|
||||||
|
|
||||||
where_sql = " AND ".join(where_parts) if where_parts else "TRUE"
|
where_sql = " AND ".join(where_parts) if where_parts else "TRUE"
|
||||||
order_sql = ", ".join(order_parts) if order_parts else None
|
order_sql = ", ".join(order_parts) if order_parts else None
|
||||||
|
|||||||
@@ -102,3 +102,13 @@ def test_data_sort_desc(api_client, valid_token_header):
|
|||||||
row["dateNotification"] for row in body["data"] if row.get("dateNotification")
|
row["dateNotification"] for row in body["data"] if row.get("dateNotification")
|
||||||
]
|
]
|
||||||
assert dates == sorted(dates, reverse=True)
|
assert dates == sorted(dates, reverse=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_data_differs_excludes_value(api_client, valid_token_header):
|
||||||
|
client, _ = api_client
|
||||||
|
base = client.get("/api/v1/data?page_size=1", headers=valid_token_header).get_json()
|
||||||
|
uid = base["data"][0]["uid"]
|
||||||
|
resp = client.get(f"/api/v1/data?uid__differs={uid}", headers=valid_token_header)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
body = resp.get_json()
|
||||||
|
assert all(row["uid"] != uid for row in body["data"])
|
||||||
|
|||||||
@@ -139,3 +139,15 @@ def test_sort_invalid_direction_raises():
|
|||||||
def test_param_without_operator_raises():
|
def test_param_without_operator_raises():
|
||||||
with pytest.raises(FilterError):
|
with pytest.raises(FilterError):
|
||||||
build_where([("uidexact", "x")], SCHEMA)
|
build_where([("uidexact", "x")], SCHEMA)
|
||||||
|
|
||||||
|
|
||||||
|
def test_differs_filter():
|
||||||
|
where, params, _ = build_where([("uid__differs", "abc")], SCHEMA)
|
||||||
|
assert where == '"uid" IS DISTINCT FROM ?'
|
||||||
|
assert params == ["abc"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_differs_filter_on_int():
|
||||||
|
where, params, _ = build_where([("annee__differs", "2020")], SCHEMA)
|
||||||
|
assert where == '"annee" IS DISTINCT FROM ?'
|
||||||
|
assert params == [2020]
|
||||||
|
|||||||
Reference in New Issue
Block a user