fix(writer): 使用哨兵值标记资源转存失败,避免重复处理
- 引入 - 修改查询条件,将 platform_song_id 为空视为未导入状态 - 在标记资源转存失败时,将 platform_song_id 设置为哨兵值 -1 - 更新测试用例,验证 platform_song_id 字段的正确更新及查询条件调整 - 删除旧的 resource_transfer_failed 字符串常量及相关引用
Showing
2 changed files
with
11 additions
and
9 deletions
| ... | @@ -3,7 +3,8 @@ import uuid | ... | @@ -3,7 +3,8 @@ import uuid |
| 3 | _SINGER_INDEX_VALUES = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ#') | 3 | _SINGER_INDEX_VALUES = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ#') |
| 4 | _SINGER_SEX_VALUES = {'M', 'F', 'C', 'U'} | 4 | _SINGER_SEX_VALUES = {'M', 'F', 'C', 'U'} |
| 5 | _SINGER_AREA_VALUES = {'华语', '欧美', '韩国', '日本', '其他'} | 5 | _SINGER_AREA_VALUES = {'华语', '欧美', '韩国', '日本', '其他'} |
| 6 | RESOURCE_TRANSFER_FAILED = 'resource_transfer_failed' | 6 | # 资源转存失败哨兵值:platform_song_id 设为 -1 表示 OSS 失败,区别于 NULL(待导入)和正整数(成功) |
| 7 | PLATFORM_SONG_ID_RESOURCE_FAILED = -1 | ||
| 7 | 8 | ||
| 8 | 9 | ||
| 9 | def _singer_index(value) -> str: | 10 | def _singer_index(value) -> str: |
| ... | @@ -50,11 +51,11 @@ def fetch_pending_yinyan_song_records(cur, limit: int) -> list[dict]: | ... | @@ -50,11 +51,11 @@ def fetch_pending_yinyan_song_records(cur, limit: int) -> list[dict]: |
| 50 | FROM yinyan_song_records | 51 | FROM yinyan_song_records |
| 51 | WHERE is_yinyan_push = FALSE | 52 | WHERE is_yinyan_push = FALSE |
| 52 | AND platform IS NOT NULL | 53 | AND platform IS NOT NULL |
| 53 | AND COALESCE(recording_id, '') != %s | 54 | AND platform_song_id IS NULL |
| 54 | ORDER BY song_id | 55 | ORDER BY song_id |
| 55 | LIMIT %s | 56 | LIMIT %s |
| 56 | """, | 57 | """, |
| 57 | (RESOURCE_TRANSFER_FAILED, limit), | 58 | (limit,), |
| 58 | ) | 59 | ) |
| 59 | rows = cur.fetchall() | 60 | rows = cur.fetchall() |
| 60 | return [{'song_id': row[0], 'record_id': row[1], 'platform': row[2]} for row in rows] | 61 | 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 | ... | @@ -210,14 +211,14 @@ def delete_qq_song_and_yinyan_record(cur, song_id: int, platform_song_id: int, s |
| 210 | 211 | ||
| 211 | 212 | ||
| 212 | def mark_yinyan_record_resource_failed(cur, song_id: int, record_id: int, platform: str) -> None: | 213 | def mark_yinyan_record_resource_failed(cur, song_id: int, record_id: int, platform: str) -> None: |
| 213 | """保留未导入状态,并标记资源转存失败,避免后续批次重复处理。""" | 214 | """保留未导入状态,并将 platform_song_id 置为哨兵值 -1,避免后续批次重复处理。""" |
| 214 | cur.execute( | 215 | cur.execute( |
| 215 | """ | 216 | """ |
| 216 | UPDATE yinyan_song_records | 217 | UPDATE yinyan_song_records |
| 217 | SET is_yinyan_push = FALSE, recording_id = %s | 218 | SET is_yinyan_push = FALSE, platform_song_id = %s |
| 218 | WHERE song_id = %s AND record_id = %s AND platform = %s AND is_yinyan_push = FALSE | 219 | WHERE song_id = %s AND record_id = %s AND platform = %s AND is_yinyan_push = FALSE |
| 219 | """, | 220 | """, |
| 220 | (RESOURCE_TRANSFER_FAILED, song_id, record_id, platform), | 221 | (PLATFORM_SONG_ID_RESOURCE_FAILED, song_id, record_id, platform), |
| 221 | ) | 222 | ) |
| 222 | 223 | ||
| 223 | 224 | ... | ... |
| ... | @@ -68,8 +68,8 @@ def test_mark_yinyan_record_resource_failed_keeps_unpushed_state_and_excludes_re | ... | @@ -68,8 +68,8 @@ def test_mark_yinyan_record_resource_failed_keeps_unpushed_state_and_excludes_re |
| 68 | sql, params = cur.execute.call_args[0] | 68 | sql, params = cur.execute.call_args[0] |
| 69 | assert 'UPDATE yinyan_song_records' in sql | 69 | assert 'UPDATE yinyan_song_records' in sql |
| 70 | assert 'is_yinyan_push = FALSE' in sql | 70 | assert 'is_yinyan_push = FALSE' in sql |
| 71 | assert 'recording_id = %s' in sql | 71 | assert 'platform_song_id = %s' in sql |
| 72 | assert params == ('resource_transfer_failed', 10, 100, '1') | 72 | assert params == (-1, 10, 100, '1') |
| 73 | 73 | ||
| 74 | 74 | ||
| 75 | def test_upsert_qq_singers_empty_does_nothing(): | 75 | 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 | ... | @@ -144,7 +144,8 @@ def test_fetch_pending_yinyan_song_records_reads_platform_for_single_platform_im |
| 144 | sql, params = cur.execute.call_args[0] | 144 | sql, params = cur.execute.call_args[0] |
| 145 | assert 'SELECT song_id, record_id, platform' in sql | 145 | assert 'SELECT song_id, record_id, platform' in sql |
| 146 | assert 'platform IS NOT NULL' in sql | 146 | assert 'platform IS NOT NULL' in sql |
| 147 | assert params == ('resource_transfer_failed', 500) | 147 | assert 'platform_song_id IS NULL' in sql |
| 148 | assert params == (500,) | ||
| 148 | assert rows == [ | 149 | assert rows == [ |
| 149 | {'song_id': 10, 'record_id': 100, 'platform': '1'}, | 150 | {'song_id': 10, 'record_id': 100, 'platform': '1'}, |
| 150 | {'song_id': 11, 'record_id': 101, 'platform': '2'}, | 151 | {'song_id': 11, 'record_id': 101, 'platform': '2'}, | ... | ... |
-
Please register or sign in to post a comment