agentic-os/newspaper-extractor/backend/app/db/models.py

62 lines
2.3 KiB
Python

from sqlalchemy import Column, Integer, String, Text, Float, ForeignKey, DateTime, JSON, Boolean
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.orm import relationship, declarative_base
from pgvector.sqlalchemy import Vector
import datetime
Base = declarative_base()
class UploadJob(Base):
__tablename__ = "upload_jobs"
id = Column(Integer, primary_key=True)
filename = Column(String)
newspaper = Column(String)
edition = Column(String)
date = Column(String)
celery_task_id = Column(String)
status = Column(String, default="PENDING")
error_message = Column(Text)
created_time = Column(DateTime, default=datetime.datetime.utcnow)
articles = relationship("Article", back_populates="upload_job")
class Article(Base):
__tablename__ = "articles"
id = Column(Integer, primary_key=True)
upload_job_id = Column(Integer, ForeignKey("upload_jobs.id"), nullable=True)
date = Column(String, index=True)
newspaper = Column(String, index=True)
edition = Column(String)
page = Column(Integer, index=True)
headline = Column(Text, index=True)
subheadline = Column(Text)
category = Column(String, index=True)
subcategory = Column(String, index=True)
language = Column(String)
author = Column(String)
text = Column(Text)
summary = Column(Text)
keywords = Column(ARRAY(String))
persons = Column(ARRAY(String))
locations = Column(ARRAY(String))
organizations = Column(ARRAY(String))
sentiment = Column(String)
image_path = Column(String)
bounding_box = Column(JSON)
confidence = Column(Float)
embedding = Column(Vector(384)) # pgvector for semantic search
content_hash = Column(String, index=True) # for dedup
human_verified = Column(Boolean, default=False, index=True)
created_time = Column(DateTime, default=datetime.datetime.utcnow)
images = relationship("ArticleImage", back_populates="article")
upload_job = relationship("UploadJob", back_populates="articles")
class ArticleImage(Base):
__tablename__ = "article_images"
id = Column(Integer, primary_key=True)
article_id = Column(Integer, ForeignKey("articles.id"))
image_path = Column(String)
caption = Column(Text)
width = Column(Integer)
height = Column(Integer)
article = relationship("Article", back_populates="images")