Gestion des filtres de dates comme du texte #76
This commit is contained in:
+17
-4
@@ -57,12 +57,18 @@ def filter_query_to_sql(filter_query: str, schema: pl.Schema) -> tuple[str, list
|
|||||||
value = raw_value.strip('"')
|
value = raw_value.strip('"')
|
||||||
|
|
||||||
if operator == "contains":
|
if operator == "contains":
|
||||||
|
if col_is_date:
|
||||||
|
target = f"CAST({quoted_col} AS VARCHAR)"
|
||||||
|
|
||||||
if col_name in ("acheteur_id", "titulaire_id"):
|
if col_name in ("acheteur_id", "titulaire_id"):
|
||||||
value = value.replace(" ", "")
|
value = value.replace(" ", "")
|
||||||
where_clause, param_list = tokenize_text_filter(col_name, value)
|
where_clause, param_list = tokenize_text_filter(
|
||||||
|
col_name, value, col_is_date
|
||||||
|
)
|
||||||
clauses.append(where_clause)
|
clauses.append(where_clause)
|
||||||
params.extend(param_list)
|
params.extend(param_list)
|
||||||
logger.debug(params)
|
logger.debug(params)
|
||||||
|
continue
|
||||||
|
|
||||||
elif operator in (">", "<"):
|
elif operator in (">", "<"):
|
||||||
target = f"CAST({quoted_col} AS VARCHAR)" if col_is_date else quoted_col
|
target = f"CAST({quoted_col} AS VARCHAR)" if col_is_date else quoted_col
|
||||||
@@ -207,15 +213,22 @@ def dashboard_filters_to_sql(
|
|||||||
return " AND ".join(clauses), params
|
return " AND ".join(clauses), params
|
||||||
|
|
||||||
|
|
||||||
def tokenize_text_filter(column: str, text: str) -> tuple[str, list]:
|
def tokenize_text_filter(
|
||||||
|
column: str, text: str, col_is_date: bool = False
|
||||||
|
) -> tuple[str, list]:
|
||||||
terms = text.split()
|
terms = text.split()
|
||||||
|
# si col_is_date alors le deuxième doit être casté en VARCHAR
|
||||||
|
if col_is_date:
|
||||||
|
quoted_col = f'CAST("{column}" AS VARCHAR)'
|
||||||
|
else:
|
||||||
|
quoted_col = '"column"'
|
||||||
|
|
||||||
conditions = [f'"{column}" IS NOT NULL', f"\"{column}\" <> ''"]
|
conditions = [f'"{column}" IS NOT NULL', f"{quoted_col} <> ''"]
|
||||||
|
|
||||||
params = []
|
params = []
|
||||||
|
|
||||||
for term in terms:
|
for term in terms:
|
||||||
conditions.append(f'"{column}" ILIKE ?')
|
conditions.append(f"{quoted_col} ILIKE ?")
|
||||||
|
|
||||||
if term.startswith("*") or term.endswith("*"):
|
if term.startswith("*") or term.endswith("*"):
|
||||||
params.append(term.replace("*", "%"))
|
params.append(term.replace("*", "%"))
|
||||||
|
|||||||
+23
-3
@@ -292,7 +292,7 @@ def test_011_observatoire_multi_param_url(dash_duo: DashComposite):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_get_distance_histogram_returns_graph():
|
def test_012_get_distance_histogram_returns_graph():
|
||||||
import polars as pl
|
import polars as pl
|
||||||
from dash import dcc
|
from dash import dcc
|
||||||
|
|
||||||
@@ -303,7 +303,7 @@ def test_get_distance_histogram_returns_graph():
|
|||||||
assert isinstance(result, dcc.Graph)
|
assert isinstance(result, dcc.Graph)
|
||||||
|
|
||||||
|
|
||||||
def test_get_distance_histogram_handles_nulls():
|
def test_013_get_distance_histogram_handles_nulls():
|
||||||
import polars as pl
|
import polars as pl
|
||||||
from dash import dcc
|
from dash import dcc
|
||||||
|
|
||||||
@@ -314,7 +314,7 @@ def test_get_distance_histogram_handles_nulls():
|
|||||||
assert isinstance(result, dcc.Graph)
|
assert isinstance(result, dcc.Graph)
|
||||||
|
|
||||||
|
|
||||||
def test_get_distance_histogram_all_nulls():
|
def test_014_get_distance_histogram_all_nulls():
|
||||||
import polars as pl
|
import polars as pl
|
||||||
from dash import dcc
|
from dash import dcc
|
||||||
|
|
||||||
@@ -322,4 +322,24 @@ def test_get_distance_histogram_all_nulls():
|
|||||||
|
|
||||||
lff = pl.LazyFrame({"titulaire_distance": pl.Series([], dtype=pl.Int64)})
|
lff = pl.LazyFrame({"titulaire_distance": pl.Series([], dtype=pl.Int64)})
|
||||||
result = get_distance_histogram(lff)
|
result = get_distance_histogram(lff)
|
||||||
|
|
||||||
assert isinstance(result, dcc.Graph)
|
assert isinstance(result, dcc.Graph)
|
||||||
|
|
||||||
|
|
||||||
|
def test_015_tableau_filter_date(dash_duo: DashComposite):
|
||||||
|
from src.app import app
|
||||||
|
|
||||||
|
dash_duo.start_server(app)
|
||||||
|
dash_duo.wait_for_text_to_equal(".logo > h1", "decp.info", timeout=4)
|
||||||
|
|
||||||
|
for page in ["tableau", "acheteurs/123", "titulaires/345"]:
|
||||||
|
dash_duo.wait_for_page(f"{dash_duo.server_url}/{page}")
|
||||||
|
filter_input = '.marches_table th[data-dash-column="dateNotification"] input'
|
||||||
|
filter_cell_result = '.marches_table td[data-dash-column="dateNotification"] p'
|
||||||
|
dash_duo.wait_for_element(filter_input, timeout=2)
|
||||||
|
_filter_input: WebElement = dash_duo.find_element(filter_input)
|
||||||
|
_filter_input.send_keys("2024") # a dateNotification that doesn't exist
|
||||||
|
_filter_input.send_keys(Keys.ENTER)
|
||||||
|
_filter_result: list[WebElement] = dash_duo.find_elements(filter_cell_result)
|
||||||
|
|
||||||
|
assert len(_filter_result) == 0
|
||||||
|
|||||||
Reference in New Issue
Block a user