diff --git a/app/db/subscribe_oper.py b/app/db/subscribe_oper.py index 52b2157a..80959db2 100644 --- a/app/db/subscribe_oper.py +++ b/app/db/subscribe_oper.py @@ -6,6 +6,19 @@ from app.db import DbOper from app.db.models.subscribe import Subscribe from app.db.models.subscribehistory import SubscribeHistory +INTEGER_FLAG_FIELDS = ("best_version", "best_version_full", "search_imdbid", "manual_total_episode") + + +def _normalize_integer_flags(payload: dict, fields: Tuple[str, ...] = INTEGER_FLAG_FIELDS) -> dict: + """ + 将历史兼容的布尔开关转换为整型值,避免 PostgreSQL 严格类型检查失败。 + """ + normalized_payload = dict(payload) + for field in fields: + if isinstance(normalized_payload.get(field), bool): + normalized_payload[field] = int(normalized_payload[field]) + return normalized_payload + class SubscribeOper(DbOper): """ @@ -37,6 +50,7 @@ class SubscribeOper(DbOper): "search_imdbid": 1 if kwargs.get('search_imdbid') else 0, "date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) }) + kwargs = _normalize_integer_flags(kwargs) if not subscribe: subscribe = Subscribe(**kwargs) subscribe.create(self._db) @@ -74,6 +88,7 @@ class SubscribeOper(DbOper): "search_imdbid": 1 if kwargs.get('search_imdbid') else 0, "date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) }) + kwargs = _normalize_integer_flags(kwargs) if not subscribe: subscribe = Subscribe(**kwargs) await subscribe.async_create(self._db) @@ -160,6 +175,7 @@ class SubscribeOper(DbOper): """ subscribe = self.get(sid) if subscribe: + payload = _normalize_integer_flags(payload) subscribe.update(self._db, payload) return subscribe @@ -188,6 +204,7 @@ class SubscribeOper(DbOper): """ # 去除kwargs中 SubscribeHistory 没有的字段 kwargs = {k: v for k, v in kwargs.items() if hasattr(SubscribeHistory, k)} + kwargs = _normalize_integer_flags(kwargs) # 更新完成订阅时间 kwargs.update({"date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}) # 去掉主键 diff --git a/tests/test_subscribe_oper.py b/tests/test_subscribe_oper.py new file mode 100644 index 00000000..e91bad84 --- /dev/null +++ b/tests/test_subscribe_oper.py @@ -0,0 +1,39 @@ +from app.db.models.subscribehistory import SubscribeHistory +from app.db.subscribe_oper import SubscribeOper + + +def test_add_history_converts_boolean_integer_flags(monkeypatch): + """ + 写入订阅历史前应把布尔开关转为整型,兼容 PostgreSQL 的严格类型检查。 + """ + captured = {} + + def fake_create(self, _db): + """ + 截获待写入模型,避免测试依赖具体数据库方言的类型宽松行为。 + """ + captured.update({ + "id": self.id, + "best_version": self.best_version, + "best_version_full": self.best_version_full, + "search_imdbid": self.search_imdbid, + }) + + monkeypatch.setattr(SubscribeHistory, "create", fake_create) + + SubscribeOper().add_history( + id=100, + name="Test Movie", + type="电影", + best_version=False, + best_version_full=True, + search_imdbid=False, + unknown_field=True, + ) + + assert captured == { + "id": None, + "best_version": 0, + "best_version_full": 1, + "search_imdbid": 0, + }