0019_content_extract_error.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. """正文提取错误落库:doc_document 增加 content_extract_error 列。
  2. Revision ID: 0019_content_extract_error
  3. Revises: 0018_sub_plan_binding
  4. Create Date: 2026-08-27
  5. 变更要点:
  6. 1. doc_document 增加 content_extract_error VARCHAR(512) NULL,
  7. 记录正文提取失败的脱敏原因(异常类型+首行信息,去除绝对路径),
  8. 供管理员在"编辑"界面排障;成功/空文本/不支持时为 NULL;
  9. 2. 存量行保持 NULL,无需回填(可经"重新解析"接口按需重提);
  10. 3. 升级为幂等:列已存在时跳过;降级仅在有失败记录时拒绝有损删除。
  11. """
  12. from __future__ import annotations
  13. from collections.abc import Sequence
  14. from alembic import op
  15. import sqlalchemy as sa
  16. revision: str = "0019_content_extract_error"
  17. down_revision: str | None = "0018_sub_plan_binding"
  18. branch_labels: str | Sequence[str] | None = None
  19. depends_on: str | Sequence[str] | None = None
  20. _TABLE = "doc_document"
  21. _COLUMN = "content_extract_error"
  22. def _existing_columns() -> set[str]:
  23. inspector = sa.inspect(op.get_bind())
  24. return {column["name"] for column in inspector.get_columns(_TABLE)}
  25. def upgrade() -> None:
  26. if _COLUMN in _existing_columns():
  27. return
  28. op.add_column(
  29. _TABLE,
  30. sa.Column(_COLUMN, sa.String(512), nullable=True),
  31. )
  32. def downgrade() -> None:
  33. if _COLUMN not in _existing_columns():
  34. return
  35. bind = op.get_bind()
  36. error_rows = bind.scalar(
  37. sa.text(
  38. f"SELECT COUNT(*) FROM {_TABLE} WHERE {_COLUMN} IS NOT NULL"
  39. )
  40. )
  41. if error_rows:
  42. raise RuntimeError(
  43. "0019已产生提取失败记录,拒绝有损降级;请先备份并按数据治理流程处理"
  44. )
  45. op.drop_column(_TABLE, _COLUMN)