From 923513f9068b9b028e93da10bd56dd1ecdacf694 Mon Sep 17 00:00:00 2001 From: TradeIn Deploy Date: Fri, 22 May 2026 10:03:17 +0500 Subject: [PATCH] =?UTF-8?q?fix(tradein):=20estimate=20500=20=E2=80=94=20Am?= =?UTF-8?q?biguousParameter=20=D0=BD=D0=B0=20NULL-=D0=BF=D0=B0=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D1=80=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Второй баг из #385 (#388 закрыл только алиас distance_m). В _fetch_analogs ORDER BY использует :target_year и :target_house_type. Когда год постройки / тип дома не заданы, они приходят NULL — psycopg шлёт их без типа, PostgreSQL не может определить тип параметра → psycopg.errors.AmbiguousParameter ($8) → 500 на каждый estimate. Фикс: явный CAST(:target_year AS integer) и CAST(:target_house_type AS text). Проверено на прод-БД через psycopg3: без CAST падает с AmbiguousParameter, с CAST — успешно (7 строк). --- tradein-mvp/backend/app/services/estimator.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tradein-mvp/backend/app/services/estimator.py b/tradein-mvp/backend/app/services/estimator.py index aa6257e3..1073534a 100644 --- a/tradein-mvp/backend/app/services/estimator.py +++ b/tradein-mvp/backend/app/services/estimator.py @@ -347,10 +347,13 @@ def _fetch_analogs( -- термом) PostgreSQL трактует имя как входную колонку listings, -- которой нет → "column distance_m does not exist". Инлайним ST_Distance. ST_Distance(geom::geography, ST_MakePoint(:lon, :lat)::geography) / 1000.0 - + CASE WHEN :target_year IS NOT NULL AND year_built IS NOT NULL - THEN abs(year_built - :target_year) / 12.0 ELSE 0 END - + CASE WHEN :target_house_type IS NOT NULL AND house_type IS NOT NULL - AND house_type <> :target_house_type + -- CAST обязателен: target_year / target_house_type приходят NULL + -- без типа → PostgreSQL "could not determine data type of parameter" + -- (AmbiguousParameter). Явный тип снимает неоднозначность. + + CASE WHEN CAST(:target_year AS integer) IS NOT NULL AND year_built IS NOT NULL + THEN abs(year_built - CAST(:target_year AS integer)) / 12.0 ELSE 0 END + + CASE WHEN CAST(:target_house_type AS text) IS NOT NULL AND house_type IS NOT NULL + AND house_type <> CAST(:target_house_type AS text) THEN 1.5 ELSE 0 END ) LIMIT 50 -- 2.45.3