class Exchange(db.Model): abbrev = db.Column(db.String(10), index=True, unique=True) name = db.Column(db.String(64), index=True, unique=True) markets = db.relationship('Market', back_populates='exchange') __repr_props__ = ('id', 'abbrev', 'name')
class Article(db.Model): title = db.Column(db.String(100)) slug = db.Column(db.String(100)) publish_date = db.Column(db.DateTime) last_updated = db.Column(db.DateTime, nullable=True) file_path = db.Column(db.String(255), nullable=True) header_image = db.Column(db.String(255), nullable=True) preview = db.Column(db.Text) html = db.Column(db.Text) author_id = db.foreign_key('User') author = db.relationship('User', back_populates='articles') article_series_id = db.foreign_key('SeriesArticle', nullable=True) article_series = db.relationship('SeriesArticle', back_populates='article', cascade='all, delete-orphan', single_parent=True) series = db.association_proxy( 'article_series', 'series', creator=lambda series: SeriesArticle(series=series)) part = db.association_proxy('article_series', 'part') category_id = db.foreign_key('Category', nullable=True) category = db.relationship('Category', back_populates='articles') article_tags = db.relationship('ArticleTag', back_populates='article', cascade='all, delete-orphan') tags = db.association_proxy('article_tags', 'tag', creator=lambda tag: ArticleTag(tag=tag)) __repr_props__ = ('id', 'title')
class DataVendor(db.Model): class Meta: repr = ('id', 'key', 'name') key = db.Column(db.String(16), index=True, unique=True) name = db.Column(db.String(64), index=True, unique=True) priority = db.Column(db.Integer) data_vendor_assets = db.relationship('AssetDataVendor', back_populates='data_vendor') assets = db.association_proxy( 'data_vendor_assets', 'asset', creator=lambda asset: AssetDataVendor(asset=asset)) data_vendor_indexes = db.relationship('IndexDataVendor', back_populates='data_vendor') indexes = db.association_proxy( 'data_vendor_indexes', 'index', creator=lambda index: IndexDataVendor(index=index)) data_vendor_items = db.relationship('DataItemVendor', back_populates='data_vendor') data_items = db.association_proxy('data_vendor_items', 'data_item')
class Index(db.Model): name = db.Column(db.String(64), index=True, unique=True) ticker = db.Column(db.String(16), index=True, unique=True) equities = db.relationship('Equity', secondary=index_equities, lazy='subquery', back_populates='indexes')
class Exchange(db.Model): class Meta: repr = ('id', 'abbrev', 'name') abbrev = db.Column(db.String(16), unique=True) name = db.Column(db.String(64), unique=True) markets = db.relationship('Market', back_populates='exchange')
class User(BaseUser): username = db.Column(db.String(64), unique=True, index=True) first_name = db.Column(db.String(64)) last_name = db.Column(db.String(64)) articles = db.relationship('Article', back_populates='author') __repr_props__ = ('id', 'username', 'email')
class User(BaseUser): class Meta: repr = ('id', 'username', 'email') username = db.Column(db.String(64), unique=True, index=True) first_name = db.Column(db.String(64)) last_name = db.Column(db.String(64)) watchlists = db.relationship('Watchlist', back_populates='user')
class Market(db.Model): abbrev = db.Column(db.String(10), index=True, unique=True) name = db.Column(db.String(64), index=True, unique=True) exchange_id = db.foreign_key('Exchange') exchange = db.relationship('Exchange', back_populates='markets') assets = db.relationship('Asset', back_populates='market') __repr_props__ = ('id', 'abbrev', 'name')
class DataItem(db.Model): key = db.Column(db.String(32)) update_frequency = db.Column(db.String(32)) update_at = db.Column(db.String(32)) data_item_vendors = db.relationship('DataItemVendor', back_populates='data_item') data_vendors = db.association_proxy( 'data_item_vendors', 'data_vendor', creator=lambda item: DataItemVendor(data_item=item))
class Category(db.Model): name = db.Column(db.String(32)) slug = db.Column(db.String(32)) articles = db.relationship('Article', back_populates='category') series = db.relationship('Series', back_populates='category') __repr_props__ = ('id', 'name') def __init__(self, name, **kwargs): super().__init__(**kwargs) self.name = name
class DataVendor(db.Model): abbrev = db.Column(db.String(10), index=True, unique=True) name = db.Column(db.String(64), index=True, unique=True) data_vendor_assets = db.relationship('AssetDataVendor', back_populates='data_vendor') assets = db.association_proxy( 'data_vendor_assets', 'asset', creator=lambda asset: AssetDataVendor(asset=asset)) __repr_props__ = ('id', 'abbrev', 'name')
class Index(db.Model): class Meta: repr = ('id', 'ticker', 'name') ticker = db.Column(db.String(16), index=True, unique=True) name = db.Column(db.String(64), index=True, unique=True) index_data_vendors = db.relationship('IndexDataVendor', back_populates='index') index_equities = db.relationship('EquityIndex', back_populates='index', cascade='all, delete-orphan') equities = db.association_proxy('index_equities', 'equity', creator=lambda equity: EquityIndex(equity=equity))
class IndexDataVendor(db.Model): """Join table between Index and DataVendor""" class Meta: repr = ('index_id', 'data_vendor_id', 'ticker') index_id = db.foreign_key('Index', primary_key=True) index = db.relationship('Index', back_populates='index_data_vendors') data_vendor_id = db.foreign_key('DataVendor', primary_key=True) data_vendor = db.relationship('DataVendor', back_populates='data_vendor_indexes') # vendor-specific index ticker (if different from canonical index ticker) _ticker = db.Column('ticker', db.String(16), nullable=True) def __init__(self, index=None, data_vendor=None, **kwargs): super(IndexDataVendor, self).__init__(**kwargs) if index: self.index = index if data_vendor: self.data_vendor = data_vendor @db.hybrid_property def ticker(self): return self._ticker or self.index.ticker @ticker.setter def ticker(self, ticker): self._ticker = ticker
class Market(db.Model): class Meta: repr = ('id', 'abbrev', 'name') abbrev = db.Column(db.String(16)) name = db.Column(db.String(64)) assets = db.relationship('Asset', back_populates='market') country_id = db.foreign_key('Country') country = db.relationship('Country', back_populates='markets') currency = db.association_proxy('country', 'currency') exchange_id = db.foreign_key('Exchange') exchange = db.relationship('Exchange', back_populates='markets')
class AssetDataVendor(db.Model): """Join table between Asset and DataVendor""" asset_id = db.foreign_key('Asset', primary_key=True) asset = db.relationship('Asset', back_populates='asset_data_vendors') data_vendor_id = db.foreign_key('DataVendor', primary_key=True) data_vendor = db.relationship('DataVendor', back_populates='data_vendor_assets') # vendor-specific ticker (if different from canonical ticker on Asset) _ticker = db.Column('ticker', db.String(16), nullable=True) __repr_props__ = ('asset_id', 'data_vendor_id', 'ticker') def __init__(self, asset=None, data_vendor=None, **kwargs): super().__init__(**kwargs) if asset: self.asset = asset if data_vendor: self.data_vendor = data_vendor @db.hybrid_property def ticker(self): return self._ticker or self.asset.ticker @ticker.setter def ticker(self, ticker): self._ticker = ticker
class Asset(db.Model): """ Base class for tradable assets. Should not be used directly. """ class Meta: repr = ('id', 'type', 'ticker') type = db.Column(db.Enum(AssetType)) # polymorphic discriminator column __mapper_args__ = { 'polymorphic_on': type, 'polymorphic_identity': AssetType.Asset, } # canonical ticker ticker = db.Column(db.String(16), index=True, unique=True) asset_data_vendors = db.relationship('AssetDataVendor', back_populates='asset', cascade='all, delete-orphan') data_vendors = db.association_proxy( 'asset_data_vendors', 'data_vendor', creator=lambda data_vendor: AssetDataVendor(data_vendor=data_vendor)) asset_watchlists = db.relationship('WatchlistAsset', back_populates='asset') market_id = db.foreign_key('Market') market = db.relationship('Market', back_populates='assets') country = db.association_proxy('market', 'country') currency = db.association_proxy('market', 'currency') exchange = db.association_proxy('market', 'exchange')
class Sector(db.Model): class Meta: repr = ('id', 'name') name = db.Column(db.String(32), index=True, unique=True) equities = db.relationship('Equity', back_populates='sector') industries = db.relationship('Industry', back_populates='sector')
class Equity(Asset): company_name = db.Column(db.String(64), index=True) indexes = db.relationship('Index', secondary=index_equities, lazy='subquery', back_populates='equities') __repr_props__ = ('id', 'ticker', 'company_name')
class Series(db.Model): title = db.Column(db.String(100)) slug = db.Column(db.String(100)) file_path = db.Column(db.String(255), nullable=True) header_image = db.Column(db.String(255), nullable=True) summary = db.Column(db.Text) series_articles = db.relationship('SeriesArticle', back_populates='series', lazy='joined', innerjoin=True, order_by='SeriesArticle.part', cascade='all, delete-orphan') articles = db.association_proxy( 'series_articles', 'article', creator=lambda article: SeriesArticle(article=article)) category_id = db.foreign_key('Category', nullable=True) category = db.relationship('Category', back_populates='series') series_tags = db.relationship('SeriesTag', back_populates='series', cascade='all, delete-orphan') tags = db.association_proxy('series_tags', 'tag', creator=lambda tag: SeriesTag(tag=tag)) __repr_props__ = ('id', 'title', 'articles') @db.on('series_articles', 'append') def on_append_series_article(self, series_article, *_): # auto increment series article part number if necessary if series_article.part is None: series_article.part = len(self.series_articles) + 1 # set the article's category to be the same as the series' category article = series_article.article article.category = self.category # set the article's tags to include the series' tags for tag in self.tags: if tag not in article.tags: article.tags.append(tag)
class Industry(db.Model): class Meta: repr = ('id', 'name', 'sector') name = db.Column(db.String(64), index=True, unique=True) equities = db.relationship('Equity', back_populates='industry') sector_id = db.foreign_key('Sector', nullable=True) sector = db.relationship('Sector', back_populates='industries')
class Country(db.Model): class Meta: repr = ('id', 'code', 'name') iso_code = db.Column(db.String(2), index=True, unique=True) # ISO 3166-1 alpha-2 iso_code3 = db.Column(db.String(3), index=True, unique=True) # ISO 3166-1 alpha-3 iso_name = db.Column(db.String(64), index=True, unique=True) # official english short name (ISO 3166/MA) _name = db.Column('name', db.String(64), index=True, nullable=True, unique=True) # common english name _native_name = db.Column('native_name', db.String(64), nullable=True, unique=True) currency_id = db.foreign_key('Currency') currency = db.relationship('Currency', back_populates='countries') markets = db.relationship('Market', back_populates='country') @db.hybrid_property def code(self): return self.iso_code @code.comparator def code(cls): return CountryCodeComparator(cls) @db.hybrid_property def name(self): return self._name or self.iso_name @name.setter def name(self, name): self._name = name @name.comparator def name(cls): return CountryNameComparator(cls) @db.hybrid_property def native_name(self): return self._native_name or self.name @native_name.setter def native_name(self, native_name): self._native_name = native_name
class AssetDataVendor(db.Model): """Join table between Asset and DataVendor""" class Meta: repr = ('asset_id', 'data_vendor_id', 'ticker') asset_id = db.foreign_key('Asset', primary_key=True) asset = db.relationship('Asset', back_populates='asset_data_vendors') data_vendor_id = db.foreign_key('DataVendor', primary_key=True) data_vendor = db.relationship('DataVendor', back_populates='data_vendor_assets') # vendor-specific ticker (if different from canonical ticker) _ticker = db.Column('ticker', db.String(16), nullable=True) minutely_last_updated = db.Column(db.DateTime(), nullable=True) daily_last_updated = db.Column(db.DateTime(), nullable=True) weekly_last_updated = db.Column(db.DateTime(), nullable=True) monthly_last_updated = db.Column(db.DateTime(), nullable=True) def __init__(self, asset=None, data_vendor=None, **kwargs): super(AssetDataVendor, self).__init__(**kwargs) if asset: self.asset = asset if data_vendor: self.data_vendor = data_vendor @db.hybrid_property def ticker(self): return self._ticker or self.asset.ticker @ticker.setter def ticker(self, ticker): self._ticker = ticker def last_updated(self, frequency: Frequency): if frequency == Frequency.Monthly: return self.monthly_last_updated elif frequency == Frequency.Weekly: return self.weekly_last_updated elif frequency == Frequency.Daily: return self.daily_last_updated return self.minutely_last_updated def set_last_updated(self, frequency: Frequency, time=None): time = time or utcnow() if frequency == Frequency.Monthly: self.monthly_last_updated = time elif frequency == Frequency.Weekly: self.weekly_last_updated = time elif frequency == Frequency.Daily: self.daily_last_updated = time else: self.minutely_last_updated = time
class Tag(db.Model): name = db.Column(db.String(32)) slug = db.Column(db.String(32)) tag_articles = db.relationship('ArticleTag', back_populates='tag') articles = db.association_proxy( 'tag_articles', 'article', creator=lambda article: ArticleTag(article=article)) tag_series = db.relationship('SeriesTag', back_populates='tag') series = db.association_proxy( 'tag_series', 'series', creator=lambda series: SeriesTag(series=series)) __repr_props__ = ('id', 'name') def __init__(self, name, **kwargs): super().__init__(**kwargs) self.name = name
class Currency(db.Model): class Meta: repr = ('id', 'code', 'name') iso_code = db.Column(db.String(3), index=True, unique=True) # ISO 4217 iso_name = db.Column(db.String(32), index=True, unique=True) # ISO 4217 _name = db.Column('name', db.String(32), index=True, nullable=True, unique=True) # common english name _plural = db.Column('plural', db.String(32), nullable=True, unique=True) symbol = db.Column(db.String(8), nullable=True) countries = db.relationship('Country', back_populates='currency') @db.hybrid_property def code(self): return self.iso_code @db.hybrid_property def name(self): return self._name or self.iso_name @name.setter def name(self, name): self._name = name @name.comparator def name(cls): return CurrencyNameComparator(cls) @db.hybrid_property def plural(self): return self._plural or '{}s'.format(self.name) @plural.setter def plural(self, plural): self._plural = plural @plural.comparator def plural(cls): return PluralComparator(cls)
class Asset(db.Model): class Meta: polymorphic = True ticker = db.Column(db.String(16), index=True, unique=True) market_id = db.foreign_key('Market') market = db.relationship('Market', back_populates='assets') exchange = db.association_proxy('market', 'exchange') asset_data_vendors = db.relationship('AssetDataVendor', back_populates='asset', cascade='all, delete-orphan') data_vendors = db.association_proxy( 'asset_data_vendors', 'data_vendor', creator=lambda data_vendor: AssetDataVendor(data_vendor=data_vendor)) __repr_props__ = ('id', 'ticker')
class Role(db.Model): """ Base :class`Role` model. Includes an :attr:`name` column and a many-to-many relationship with the :class:`User` model via the intermediary :class:`UserRole` join table. """ class Meta: lazy_mapped = True repr = ('id', 'name') name = db.Column(db.String(64), unique=True, index=True) role_users = db.relationship('UserRole', back_populates='role', cascade='all, delete-orphan') users = db.association_proxy('role_users', 'user', creator=lambda user: UserRole(user=user)) def __hash__(self): return hash(self.name)
class User(db.Model): """ Base :class:`User` model. Includes :attr:`email`, :attr:`password`, :attr:`active`, and :attr:`confirmed_at` columns, and a many-to-many relationship to the :class:`Role` model via the intermediary :class:`UserRole` join table. """ class Meta: lazy_mapped = True repr = ('id', 'email', 'active') email = db.Column( db.String(64), unique=True, index=True, info=dict( required=_('flask_unchained.bundles.security:email_required'), validators=[EmailValidator])) _password = db.Column( 'password', db.String, info=dict( required=_('flask_unchained.bundles.security:password_required'))) active = db.Column(db.Boolean(name='active'), default=False) confirmed_at = db.Column(db.DateTime(), nullable=True) user_roles = db.relationship('UserRole', back_populates='user', cascade='all, delete-orphan') roles = db.association_proxy('user_roles', 'role', creator=lambda role: UserRole(role=role)) @db.hybrid_property def password(self): return self._password @password.setter @unchained.inject('security_utils_service') def password(self, password, security_utils_service=injectable): self._password = security_utils_service.hash_password(password) @classmethod def validate_password(cls, password): if password and len(password) < MIN_PASSWORD_LENGTH: raise db.ValidationError(f'Password must be at least ' f'{MIN_PASSWORD_LENGTH} characters long.') @unchained.inject('security_utils_service') def get_auth_token(self, security_utils_service=injectable): """ Returns the user's authentication token. """ return security_utils_service.get_auth_token(self) def has_role(self, role): """ Returns `True` if the user identifies with the specified role. :param role: A role name or :class:`Role` instance """ if isinstance(role, str): return role in (role.name for role in self.roles) else: return role in self.roles @property def is_authenticated(self): return True @property def is_anonymous(self): return False
class User(BaseUser): username = db.Column(db.String(64), nullable=True) first_name = db.Column(db.String(64), nullable=True) last_name = db.Column(db.String(64), nullable=True)
class ContactSubmission(db.Model): name = db.Column(db.String(64)) email = db.Column(db.String(64)) message = db.Column(db.Text)
class ExerciseType(db.Model): name = db.Column(db.String(length=64)) exercises = db.relationship("Exercise", back_populates='exercise_type')