| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- from __future__ import annotations
- from collections.abc import Iterable
- from sqlalchemy import select, update
- from sqlalchemy.dialects.mysql import insert
- from supply_infra.db.models.multi_demand_video_detail import MultiDemandVideoDetail
- from supply_infra.db.repositories.base import BaseRepository
- _BATCH_SIZE = 1000
- class MultiDemandVideoDetailRepository(BaseRepository[MultiDemandVideoDetail]):
- """需求池视频详情表 — 按 vid 唯一键增量写入。"""
- model = MultiDemandVideoDetail
- def get_existing_vids(self, vids: Iterable[str]) -> set[str]:
- """返回 vids 中已存在于表内的视频 id。"""
- vid_list = [v for v in vids if v]
- if not vid_list:
- return set()
- existing: set[str] = set()
- for i in range(0, len(vid_list), _BATCH_SIZE):
- batch = vid_list[i : i + _BATCH_SIZE]
- stmt = select(MultiDemandVideoDetail.vid).where(
- MultiDemandVideoDetail.vid.in_(batch)
- )
- existing.update(str(v) for v in self.session.scalars(stmt).all() if v)
- return existing
- def list_by_vids(self, vids: Iterable[str]) -> dict[str, MultiDemandVideoDetail]:
- """按 vid 批量查询,返回 vid → row。"""
- vid_list = [v for v in vids if v]
- if not vid_list:
- return {}
- result: dict[str, MultiDemandVideoDetail] = {}
- for i in range(0, len(vid_list), _BATCH_SIZE):
- batch = vid_list[i : i + _BATCH_SIZE]
- stmt = select(MultiDemandVideoDetail).where(
- MultiDemandVideoDetail.vid.in_(batch)
- )
- for row in self.session.scalars(stmt).all():
- if row.vid:
- result[str(row.vid)] = row
- return result
- def list_vids_missing_title(self) -> list[str]:
- """返回 title 为空的全部 vid。"""
- stmt = select(MultiDemandVideoDetail.vid).where(
- (MultiDemandVideoDetail.title.is_(None)) | (MultiDemandVideoDetail.title == "")
- )
- return [str(v) for v in self.session.scalars(stmt).all() if v]
- def list_vids_missing_points(self) -> list[str]:
- """返回灵感点/目的点/关键点任一字段为空的全部 vid。"""
- stmt = select(MultiDemandVideoDetail.vid).where(
- MultiDemandVideoDetail.inspiration_points_json.is_(None)
- | MultiDemandVideoDetail.purpose_points_json.is_(None)
- | MultiDemandVideoDetail.key_points_json.is_(None)
- )
- return [str(v) for v in self.session.scalars(stmt).all() if v]
- def list_vids_missing_urls(self) -> list[str]:
- """返回 url1 或 url2 为空的全部 vid。"""
- stmt = select(MultiDemandVideoDetail.vid).where(
- MultiDemandVideoDetail.url1.is_(None)
- | (MultiDemandVideoDetail.url1 == "")
- | MultiDemandVideoDetail.url2.is_(None)
- | (MultiDemandVideoDetail.url2 == "")
- )
- return [str(v) for v in self.session.scalars(stmt).all() if v]
- def bulk_insert_ignore(self, rows: list[dict]) -> int:
- """批量插入,MySQL 自动忽略 vid 重复行。"""
- if not rows:
- return 0
- inserted = 0
- for i in range(0, len(rows), _BATCH_SIZE):
- batch = rows[i : i + _BATCH_SIZE]
- stmt = insert(MultiDemandVideoDetail).values(batch).prefix_with("IGNORE")
- result = self.session.execute(stmt)
- inserted += result.rowcount
- return inserted
- def update_titles(self, titles_by_vid: dict[str, str]) -> int:
- """按 vid 批量更新 title。"""
- if not titles_by_vid:
- return 0
- updated = 0
- for vid, title in titles_by_vid.items():
- stmt = (
- update(MultiDemandVideoDetail)
- .where(MultiDemandVideoDetail.vid == vid)
- .values(title=title)
- )
- result = self.session.execute(stmt)
- updated += result.rowcount or 0
- return updated
- def update_urls(self, urls_by_vid: dict[str, dict[str, str | None]]) -> int:
- """按 vid 批量更新 url1/url2(values 为落库字段名 → URL 文本)。"""
- if not urls_by_vid:
- return 0
- updated = 0
- for vid, values in urls_by_vid.items():
- if not values:
- continue
- stmt = (
- update(MultiDemandVideoDetail)
- .where(MultiDemandVideoDetail.vid == vid)
- .values(**values)
- )
- result = self.session.execute(stmt)
- updated += result.rowcount or 0
- return updated
- def update_points(self, points_by_vid: dict[str, dict[str, str | None]]) -> int:
- """按 vid 批量更新灵感点/目的点/关键点(values 为落库字段名 → JSON 文本)。"""
- if not points_by_vid:
- return 0
- updated = 0
- for vid, values in points_by_vid.items():
- if not values:
- continue
- stmt = (
- update(MultiDemandVideoDetail)
- .where(MultiDemandVideoDetail.vid == vid)
- .values(**values)
- )
- result = self.session.execute(stmt)
- updated += result.rowcount or 0
- return updated
|