feat(ttp): E.3.3 repository — insert_tags + listing rollups (dual backend)
Dialect-split: portable rollup queries on TTPMixin; bulk insert with ON CONFLICT DO NOTHING / INSERT IGNORE in the per-dialect repos. Confidence-floor (< 0.3) drop applied at mixin layer before the dialect hook. BaseRepository now declares the six TTP methods abstract. Tests in tests/web/db/test_ttp_repo.py flipped from pytest.fail stubs to real dual-backend behavioral tests; tests/ttp/test_confidence.py drop-below-floor xfail removed.
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from sqlalchemy import func, select, text, literal_column
|
||||
from sqlalchemy.dialects.sqlite import insert as sqlite_insert
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
||||
|
||||
|
||||
from decnet.config import _ROOT
|
||||
from decnet.web.db.models import Log
|
||||
from decnet.web.db.models import Log, TTPTag
|
||||
from decnet.web.db.sqlite.database import get_async_engine
|
||||
from decnet.web.db.sqlmodel_repo import SQLModelRepository
|
||||
|
||||
@@ -83,6 +84,21 @@ class SQLiteRepository(SQLModelRepository):
|
||||
# SQLite stores JSON as text; json_extract is the canonical accessor.
|
||||
return text(f"json_extract(fields, '$.{key}') = :val")
|
||||
|
||||
async def _insert_tags_or_ignore(self, rows: list[TTPTag]) -> int:
|
||||
"""Bulk-insert with SQLite's ``ON CONFLICT DO NOTHING`` on the
|
||||
``uuid`` PK. Returns rowcount of newly-inserted rows; the
|
||||
skipped duplicates do not count.
|
||||
"""
|
||||
if not rows:
|
||||
return 0
|
||||
payload = [r.model_dump() for r in rows]
|
||||
stmt = sqlite_insert(TTPTag.__table__).values(payload) # type: ignore[attr-defined]
|
||||
stmt = stmt.on_conflict_do_nothing(index_elements=["uuid"])
|
||||
async with self._session() as session:
|
||||
result = await session.execute(stmt)
|
||||
await session.commit()
|
||||
return int(result.rowcount or 0)
|
||||
|
||||
async def get_log_histogram(
|
||||
self,
|
||||
search: Optional[str] = None,
|
||||
|
||||
Reference in New Issue
Block a user