Commit 7ef2362f 7ef2362fc746f0e3bc1bf3fb964589428bbc6e3f by 沈秋雨

fix(writer): 使用哨兵值标记资源转存失败,避免重复处理

- 引入
- 修改查询条件,将 platform_song_id 为空视为未导入状态
- 在标记资源转存失败时,将 platform_song_id 设置为哨兵值 -1
- 更新测试用例,验证 platform_song_id 字段的正确更新及查询条件调整
- 删除旧的 resource_transfer_failed 字符串常量及相关引用
1 parent 2911f147
......@@ -3,7 +3,8 @@ import uuid
_SINGER_INDEX_VALUES = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ#')
_SINGER_SEX_VALUES = {'M', 'F', 'C', 'U'}
_SINGER_AREA_VALUES = {'华语', '欧美', '韩国', '日本', '其他'}
RESOURCE_TRANSFER_FAILED = 'resource_transfer_failed'
# 资源转存失败哨兵值:platform_song_id 设为 -1 表示 OSS 失败,区别于 NULL(待导入)和正整数(成功)
PLATFORM_SONG_ID_RESOURCE_FAILED = -1
def _singer_index(value) -> str:
......@@ -50,11 +51,11 @@ def fetch_pending_yinyan_song_records(cur, limit: int) -> list[dict]:
FROM yinyan_song_records
WHERE is_yinyan_push = FALSE
AND platform IS NOT NULL
AND COALESCE(recording_id, '') != %s
AND platform_song_id IS NULL
ORDER BY song_id
LIMIT %s
""",
(RESOURCE_TRANSFER_FAILED, limit),
(limit,),
)
rows = cur.fetchall()
return [{'song_id': row[0], 'record_id': row[1], 'platform': row[2]} for row in rows]
......@@ -210,14 +211,14 @@ def delete_qq_song_and_yinyan_record(cur, song_id: int, platform_song_id: int, s
def mark_yinyan_record_resource_failed(cur, song_id: int, record_id: int, platform: str) -> None:
"""保留未导入状态,并标记资源转存失败,避免后续批次重复处理。"""
"""保留未导入状态,并将 platform_song_id 置为哨兵值 -1,避免后续批次重复处理。"""
cur.execute(
"""
UPDATE yinyan_song_records
SET is_yinyan_push = FALSE, recording_id = %s
SET is_yinyan_push = FALSE, platform_song_id = %s
WHERE song_id = %s AND record_id = %s AND platform = %s AND is_yinyan_push = FALSE
""",
(RESOURCE_TRANSFER_FAILED, song_id, record_id, platform),
(PLATFORM_SONG_ID_RESOURCE_FAILED, song_id, record_id, platform),
)
......
......@@ -68,8 +68,8 @@ def test_mark_yinyan_record_resource_failed_keeps_unpushed_state_and_excludes_re
sql, params = cur.execute.call_args[0]
assert 'UPDATE yinyan_song_records' in sql
assert 'is_yinyan_push = FALSE' in sql
assert 'recording_id = %s' in sql
assert params == ('resource_transfer_failed', 10, 100, '1')
assert 'platform_song_id = %s' in sql
assert params == (-1, 10, 100, '1')
def test_upsert_qq_singers_empty_does_nothing():
......@@ -144,7 +144,8 @@ def test_fetch_pending_yinyan_song_records_reads_platform_for_single_platform_im
sql, params = cur.execute.call_args[0]
assert 'SELECT song_id, record_id, platform' in sql
assert 'platform IS NOT NULL' in sql
assert params == ('resource_transfer_failed', 500)
assert 'platform_song_id IS NULL' in sql
assert params == (500,)
assert rows == [
{'song_id': 10, 'record_id': 100, 'platform': '1'},
{'song_id': 11, 'record_id': 101, 'platform': '2'},
......