mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-09 09:26:55 +08:00
fix: 订阅年份写库前转为字符串,避免音乐订阅时报类型错误
音乐识别链路返回的年份是数字,而订阅表 year 列为字符串, 直接写入会导致 PostgreSQL 严格类型检查失败(expected str, got int)。 在 SubscribeOper 写库前统一做字符串归一化,并补充回归测试。
This commit is contained in:
@@ -21,6 +21,16 @@ def _normalize_integer_flags(payload: dict, fields: Tuple[str, ...] = INTEGER_FL
|
|||||||
return normalized_payload
|
return normalized_payload
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_year(year: Optional[int | str]) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
订阅表的 year 列为字符串类型,而识别链路的媒体年份可能是数字
|
||||||
|
(音乐等来源),写库前统一转换为字符串避免数据库类型错误。
|
||||||
|
"""
|
||||||
|
if year is None:
|
||||||
|
return None
|
||||||
|
return str(year)
|
||||||
|
|
||||||
|
|
||||||
class SubscribeOper(DbOper):
|
class SubscribeOper(DbOper):
|
||||||
"""
|
"""
|
||||||
订阅管理
|
订阅管理
|
||||||
@@ -55,7 +65,7 @@ class SubscribeOper(DbOper):
|
|||||||
subscribe = Subscribe.exists(self._db, **identity_params)
|
subscribe = Subscribe.exists(self._db, **identity_params)
|
||||||
kwargs.update({
|
kwargs.update({
|
||||||
"name": mediainfo.title,
|
"name": mediainfo.title,
|
||||||
"year": mediainfo.year,
|
"year": _normalize_year(mediainfo.year),
|
||||||
"type": mediainfo.type.value,
|
"type": mediainfo.type.value,
|
||||||
"tmdbid": mediainfo.tmdb_id,
|
"tmdbid": mediainfo.tmdb_id,
|
||||||
"imdbid": mediainfo.imdb_id,
|
"imdbid": mediainfo.imdb_id,
|
||||||
@@ -117,7 +127,7 @@ class SubscribeOper(DbOper):
|
|||||||
subscribe = await Subscribe.async_exists(self._db, **identity_params)
|
subscribe = await Subscribe.async_exists(self._db, **identity_params)
|
||||||
kwargs.update({
|
kwargs.update({
|
||||||
"name": mediainfo.title,
|
"name": mediainfo.title,
|
||||||
"year": mediainfo.year,
|
"year": _normalize_year(mediainfo.year),
|
||||||
"type": mediainfo.type.value,
|
"type": mediainfo.type.value,
|
||||||
"tmdbid": mediainfo.tmdb_id,
|
"tmdbid": mediainfo.tmdb_id,
|
||||||
"imdbid": mediainfo.imdb_id,
|
"imdbid": mediainfo.imdb_id,
|
||||||
|
|||||||
@@ -120,6 +120,29 @@ def test_music_subscribe_persists_release_cover_as_poster_and_backdrop():
|
|||||||
assert payload["backdrop"] == media.cover_url
|
assert payload["backdrop"] == media.cover_url
|
||||||
|
|
||||||
|
|
||||||
|
def test_music_subscribe_persists_numeric_year_as_string():
|
||||||
|
"""音乐识别链路的年份可能是数字,写库前必须转字符串避免 PostgreSQL 类型错误。"""
|
||||||
|
persisted = SimpleNamespace(id=93)
|
||||||
|
created = SimpleNamespace(create=MagicMock())
|
||||||
|
media = MusicInfo(
|
||||||
|
source="musicbrainz",
|
||||||
|
media_id="2af54891-e954-40e8-8b90-b7e98c740f21",
|
||||||
|
title="心愿",
|
||||||
|
year=2025,
|
||||||
|
cover_url="https://coverartarchive.org/release/example/front-500",
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch("app.db.subscribe_oper.Subscribe") as subscribe_model:
|
||||||
|
subscribe_model.exists.side_effect = [None, persisted]
|
||||||
|
subscribe_model.return_value = created
|
||||||
|
|
||||||
|
sid, _ = SubscribeOper(db=object()).add(mediainfo=media, season=None)
|
||||||
|
|
||||||
|
assert sid == 93
|
||||||
|
payload = subscribe_model.call_args.kwargs
|
||||||
|
assert payload["year"] == "2025"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("episode_group", [None, "eg-1"])
|
@pytest.mark.parametrize("episode_group", [None, "eg-1"])
|
||||||
def test_async_add_scopes_duplicate_lookup_by_episode_group(episode_group):
|
def test_async_add_scopes_duplicate_lookup_by_episode_group(episode_group):
|
||||||
"""异步新增与同步路径使用相同的剧集组身份契约。"""
|
"""异步新增与同步路径使用相同的剧集组身份契约。"""
|
||||||
|
|||||||
Reference in New Issue
Block a user