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
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'))
|