0002_document_processing.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. """document processing workflow
  2. Revision ID: 0002_document_processing
  3. Revises: 0001_initial
  4. Create Date: 2026-10-09
  5. """
  6. from __future__ import annotations
  7. import sqlalchemy as sa
  8. from alembic import op
  9. from sqlalchemy.dialects import mysql
  10. revision = "0002_document_processing"
  11. down_revision = "0001_initial"
  12. branch_labels = None
  13. depends_on = None
  14. def upgrade() -> None:
  15. op.add_column(
  16. "business_documents",
  17. sa.Column(
  18. "document_type",
  19. sa.String(length=32),
  20. nullable=False,
  21. server_default="",
  22. ),
  23. )
  24. op.create_index(
  25. "ix_business_documents_document_type",
  26. "business_documents",
  27. ["document_type"],
  28. )
  29. op.create_table(
  30. "document_extraction_templates",
  31. sa.Column("code", sa.String(length=64), nullable=False),
  32. sa.Column("name", sa.String(length=128), nullable=False),
  33. sa.Column("document_type", sa.String(length=32), nullable=False),
  34. sa.Column("description", sa.Text(), nullable=False),
  35. sa.Column("version", sa.String(length=32), nullable=False),
  36. sa.Column("prompt", sa.Text(), nullable=False),
  37. sa.Column("extraction_schema", sa.JSON(), nullable=False),
  38. sa.Column("enabled", sa.Boolean(), nullable=False),
  39. sa.Column("id", sa.String(length=32), nullable=False),
  40. sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
  41. sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
  42. sa.PrimaryKeyConstraint("id", name="pk_document_extraction_templates"),
  43. sa.UniqueConstraint("code", name="uq_document_extraction_templates_code"),
  44. )
  45. op.create_index(
  46. "ix_document_extraction_templates_code",
  47. "document_extraction_templates",
  48. ["code"],
  49. )
  50. op.create_index(
  51. "ix_document_extraction_templates_document_type",
  52. "document_extraction_templates",
  53. ["document_type"],
  54. )
  55. op.create_index(
  56. "ix_document_extraction_templates_enabled",
  57. "document_extraction_templates",
  58. ["enabled"],
  59. )
  60. op.create_table(
  61. "document_processing_runs",
  62. sa.Column("document_id", sa.String(length=32), nullable=False),
  63. sa.Column("template_id", sa.String(length=32), nullable=True),
  64. sa.Column("status", sa.String(length=32), nullable=False),
  65. sa.Column("stage", sa.String(length=32), nullable=False),
  66. sa.Column("progress", sa.Integer(), nullable=False),
  67. sa.Column("document_type", sa.String(length=32), nullable=False),
  68. sa.Column("parser_engine", sa.String(length=32), nullable=False),
  69. sa.Column("parsed_markdown_path", sa.String(length=512), nullable=False),
  70. sa.Column(
  71. "parsed_markdown",
  72. sa.Text().with_variant(mysql.LONGTEXT(), "mysql"),
  73. nullable=False,
  74. ),
  75. sa.Column("model_output", sa.JSON(), nullable=False),
  76. sa.Column("error", sa.Text(), nullable=False),
  77. sa.Column("started_at", sa.DateTime(timezone=True), nullable=True),
  78. sa.Column("finished_at", sa.DateTime(timezone=True), nullable=True),
  79. sa.Column("metadata", sa.JSON(), nullable=False),
  80. sa.Column("id", sa.String(length=32), nullable=False),
  81. sa.Column("created_at", sa.DateTime(timezone=True), nullable=False),
  82. sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False),
  83. sa.ForeignKeyConstraint(
  84. ["document_id"],
  85. ["business_documents.id"],
  86. name="fk_document_processing_runs_document",
  87. ondelete="CASCADE",
  88. ),
  89. sa.ForeignKeyConstraint(
  90. ["template_id"],
  91. ["document_extraction_templates.id"],
  92. name="fk_document_processing_runs_template",
  93. ondelete="SET NULL",
  94. ),
  95. sa.PrimaryKeyConstraint("id", name="pk_document_processing_runs"),
  96. )
  97. op.create_index(
  98. "ix_document_processing_runs_document_id",
  99. "document_processing_runs",
  100. ["document_id"],
  101. )
  102. op.create_index(
  103. "ix_document_processing_runs_template_id",
  104. "document_processing_runs",
  105. ["template_id"],
  106. )
  107. op.create_index(
  108. "ix_document_processing_runs_status",
  109. "document_processing_runs",
  110. ["status"],
  111. )
  112. op.create_index(
  113. "ix_document_processing_runs_document_type",
  114. "document_processing_runs",
  115. ["document_type"],
  116. )
  117. def downgrade() -> None:
  118. op.drop_index(
  119. "ix_document_processing_runs_document_type",
  120. table_name="document_processing_runs",
  121. )
  122. op.drop_index(
  123. "ix_document_processing_runs_status",
  124. table_name="document_processing_runs",
  125. )
  126. op.drop_index(
  127. "ix_document_processing_runs_template_id",
  128. table_name="document_processing_runs",
  129. )
  130. op.drop_index(
  131. "ix_document_processing_runs_document_id",
  132. table_name="document_processing_runs",
  133. )
  134. op.drop_table("document_processing_runs")
  135. op.drop_index(
  136. "ix_document_extraction_templates_enabled",
  137. table_name="document_extraction_templates",
  138. )
  139. op.drop_index(
  140. "ix_document_extraction_templates_document_type",
  141. table_name="document_extraction_templates",
  142. )
  143. op.drop_index(
  144. "ix_document_extraction_templates_code",
  145. table_name="document_extraction_templates",
  146. )
  147. op.drop_table("document_extraction_templates")
  148. op.drop_index(
  149. "ix_business_documents_document_type",
  150. table_name="business_documents",
  151. )
  152. op.drop_column("business_documents", "document_type")