You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.8 KiB
Python

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean, Numeric, BigInteger, Text, Table, ARRAY
from sqlalchemy.orm import relationship, backref
from sqlalchemy.sql import expression, and_
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime as DateTimeType
class utcnow(expression.FunctionElement):
type = DateTimeType()
@compiles(utcnow, 'postgresql')
def pg_utcnow(element, compiler, **kw):
return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
Base = declarative_base()
class DBMixin:
id = Column(BigInteger, primary_key=True, autoincrement=True)
created_date = Column(DateTime, server_default=utcnow())
modified_date = Column(DateTime, server_default=utcnow(), onupdate=utcnow())
def to_dict(self):
d = self.__dict__.copy()
if '_sa_instance_state' in d:
d.pop('_sa_instance_state')
return d
def ReferenceCol(tablename, nullable=False, **kw):
return Column(ForeignKey('{}.id'.format(tablename)), nullable=nullable, **kw)
categories = Table('news_source_category', Base.metadata,
Column('news_source_id,', ForeignKey('news_source.id')),
Column('category_id,', ForeignKey('category.id'))
)
tags = Table('news_article_tag', Base.metadata,
Column('news_article_id', ForeignKey('news_article.id')),
Column('tag_id', ForeignKey('tag.id')),
)
class Tag(DBMixin, Base):
__tablename__ = 'tag'
tag_name = Column(Text, unique=True)
@staticmethod
def get_or_create(session, name):
try:
return session.query(Tag).filter_by(tag_name=name).one()
except:
return Tag(tag_name=name)
class Category(DBMixin, Base):
__tablename__ = 'category'
category_name = Column(Text, unique=True)
@staticmethod
def get_or_create(session, name):
try:
return session.query(Category).filter_by(category_name=name).one()
except:
return Category(category_name=name)
class NewsSource(DBMixin, Base):
__tablename__ = 'news_source'
url = Column(Text, unique=True)
source_name = Column(Text)
source_type = Column(Text)
categories = relationship('Category', secondary=categories,
backref=backref('news_sources', lazy='dynamic'))
class NewsArticle(DBMixin, Base):
__tablename__ = 'news_article'
news_source_id = ReferenceCol('news_source')
url = Column(Text, unique=True)
title = Column(Text)
authors = Column(ARRAY(Text))
publish_date = Column(DateTime)
news_blob = Column(Text)
news_source = relationship('NewsSource', backref=backref('articles', lazy='dynamic'))
tags = relationship('Tag', secondary=tags, backref=backref('articles', lazy='dynamic'))