62 lines
2.3 KiB
Python
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")
|