diff --git a/news/app.py b/news/app.py index 481fbb5..107551d 100644 --- a/news/app.py +++ b/news/app.py @@ -20,7 +20,7 @@ routes = [ _settings = { 'DATABASE': { - 'URL': 'postgresql://@localhost/news', + 'URL': 'postgresql://apistar:local@localhost/news', 'METADATA': Base.metadata }, 'RENDERERS': [JSONRenderer()] diff --git a/news/models.py b/news/models.py index 430bdd4..3dc6ab0 100644 --- a/news/models.py +++ b/news/models.py @@ -1,7 +1,7 @@ from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean, Numeric +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 +from sqlalchemy.sql import expression, and_ from sqlalchemy.ext.compiler import compiles from sqlalchemy.types import DateTime as DateTimeType @@ -19,7 +19,7 @@ Base = declarative_base() class DBMixin: - id = Column(Integer, primary_key=True, autoincrement=True) + id = Column(BigInteger, primary_key=True, autoincrement=True) created_date = Column(DateTime, server_default=utcnow()) modified_date = Column(DateTime, server_default=utcnow(), onupdate=utcnow()) @@ -33,3 +33,58 @@ class DBMixin: 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'))