Commit graph

3 commits

Author SHA1 Message Date
lekss361
c8ac1fa732 fix(objective parser): restore bulk executemany in stream _flush
Reviewer flagged perf regression vs PR #315 — _flush loop'ил per-row
через db.execute(stmt, dict) вместо bulk db.execute(stmt, list).
Для 324k лотов это 648k round-trips × 2 sync/неделю.

Восстановлен SQLAlchemy executemany через list[dict] + commit
cadence 5 batch (2500 строк) как в #315.

Также убран неиспользуемый импорт datetime (ruff F401).

Per #318 (comment)
2026-05-17 20:48:27 +03:00
lekss361
8d0e67d03b fix(objective parser): wrap bytes-iter in file-like reader for ijson
ijson.items() ожидает file-like с .read(n), а resp.iter_bytes(65536)
возвращает generator bytes → ijson интерпретирует chunks как
(prefix, event, value) tuples → ValueError "too many values to unpack
(expected 3, got 65536)".

Добавлен _IterBytesReader адаптер: собирает chunks в bytearray buffer
и отдаёт через .read(n). Добавлена parse_lots_pf_stream — streaming-
вариант парсера для больших ответов (>100 МБ) через ijson.items(),
с автоматической обёрткой stream если у него нет .read.

Glitchtip BACKEND-1K (release 389e141, 3 events) — silent fail в
inner try/except → rows_extracted=NULL, lots=0 после "успешных" runs.
2026-05-17 19:58:59 +03:00
lekss361
aaa5d44e77 feat(objective): integrate api.objctv.ru — auth, schema, weekly sync
backend/app/services/scrapers/objective.py:
  ObjectiveClient — GetToken (Bearer cached в Redis 25 min TTL) +
  GetReport v2 с UseDdu/UseDkp. 4 высокоуровневых метода:
  report_corpuses_summary, report_lots_summary, report_corpuses_per_flat,
  report_lots_per_flat. Retry 401/429/5xx, rate-limit 500ms, brotli.
backend/app/workers/tasks/scrape_objective.py:
  Celery task sync_objective_group — еженедельно тянет 4 канон. отчёта по
  группе, raw payload в objective_raw_reports.
celery_app.py: +include + beat «0 5 * * mon».
data/sql/68_schema_objective.sql: 6 таблиц — runs, raw_reports (jsonb),
oks (готовые ТЭП + escrow/debt), lots, lots_history (per-flat per-day),
complex_mapping (Objective ↔ domrf_kn_objects, is_reviewed workflow).
data/sql/69_objective_smoke.py: stand-alone GetToken + 4 отчёта →
data/raw/objective_smoke/<ts>/. Используется один раз чтобы понять
реальную схему payload перед написанием parser-слоя.
config: OBJECTIVE_API_KEY, OBJECTIVE_DEFAULT_GROUP=Екатеринбург,
OBJECTIVE_SYNC_CRON='0 5 * * mon'.
2026-05-07 21:04:00 +03:00