SQLAlchemy and Pandas
config.py:
DATABASE_URI = 'mysql://invest:secret@localhost/invest'
invest_codegen:
This was generated from the database using sqlacodegen.
# coding: utf-8
from sqlalchemy import CHAR, Column, DECIMAL, DateTime, Index, String, Table, text
from sqlalchemy.dialects.mysql import INTEGER
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
metadata = Base.metadata
class Portfolio(Base):
__tablename__ = 'Portfolios'
Portfolio = Column(CHAR(4), primary_key=True)
GUID = Column(CHAR(36), nullable=False)
t_PricesForStocksToWatch = Table(
'PricesForStocksToWatch', metadata,
Column('Ticker', String(8), nullable=False, unique=True),
Column('TimeStamp', DateTime, nullable=False),
Column('High', DECIMAL(15, 2), nullable=False),
Column('Low', DECIMAL(15, 2), nullable=False),
Column('Open', DECIMAL(15, 2), nullable=False),
Column('Close', DECIMAL(15, 2), nullable=False),
Column('Volume', DECIMAL(15, 0), nullable=False)
)
t_StockOwnership = Table(
'StockOwnership', metadata,
Column('Portfolio', CHAR(4), nullable=False),
Column('Ticker', String(8), nullable=False),
Column('Period', INTEGER(6), nullable=False, comment="YYYYQQ, set QQ=00 for full year when if quarterly data isn't saved"),
Column('NoShares', DECIMAL(15, 0), nullable=False),
Column('EPS', DECIMAL(15, 2), nullable=False),
Column('DPS', DECIMAL(15, 2), nullable=False),
Column('Earnings', DECIMAL(15, 0), nullable=False, comment='EPS x NoShares'),
Column('RetainedEarnings', DECIMAL(15, 0), nullable=False, comment='(EPS-DPS) x NoShares'),
Column('Dividends', DECIMAL(15, 0), nullable=False, comment='DPS x NoShares'),
Index('Ticker', 'Ticker', 'Portfolio', 'Period', unique=True)
)
t_StocksToWatch = Table(
'StocksToWatch', metadata,
Column('Ticker', String(8), nullable=False),
Column('Instrument', INTEGER(11), nullable=False),
Column('Action', CHAR(1), nullable=False, comment='(B)uy, (S)ell'),
Column('Price', DECIMAL(15, 0), nullable=False),
Column('Currency', CHAR(3), nullable=False),
Column('LastUpdate', DateTime, nullable=False),
Index('Ticker', 'Ticker', 'Action', 'Price', 'Currency', unique=True)
)
class TickerDatum(Base):
__tablename__ = 'TickerData'
Ticker = Column(String(8), primary_key=True, nullable=False, server_default=text("''"))
TS_Name = Column(String(100), primary_key=True, nullable=False, server_default=text("''"))
TS_Type = Column(CHAR(1), primary_key=True, nullable=False)
TS_Index = Column(String(10), primary_key=True, nullable=False, server_default=text("''"))
Value = Column(DECIMAL(15, 4))
Note = Column(String(255))
class Transaction(Base):
__tablename__ = 'Transactions'
TransID = Column(INTEGER(11), primary_key=True)
TransDate = Column(DateTime, nullable=False)
Portfolio = Column(CHAR(4))
Ticker = Column(String(20))
ShareType = Column(CHAR(1), comment='(S)Share, (B)ond')
TransType = Column(CHAR(1), nullable=False, comment='(B)uy, (S)ell, (D)ividend, (W)ithdraw, d(E)posit, s(P)lit, (I)inlösen')
NoShares = Column(DECIMAL(15, 5))
PerShare = Column(DECIMAL(15, 2))
Amount = Column(DECIMAL(15, 2), nullable=False, comment='should equal NoShares x PerShare x sign')
Courtage = Column(DECIMAL(15, 2), nullable=False)
TransAmount = Column(DECIMAL(15, 2), nullable=False, comment='should equal Amount + Courtage')
Currency = Column(CHAR(3), nullable=False)
Depo = Column(String(20))
Note = Column(String(255))
invest.py
# coding: utf-8
#
# 2020-07-25, Jonas Colmsjö
#
# http://google.github.io/styleguide/pyguide.html
#
# conda install -c auto colanderalchemy
from sqlalchemy import CHAR, Column, DECIMAL, DateTime, Index, String, Table, text
from sqlalchemy.dialects.mysql import INTEGER
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, mapper
import pandas as pd
from config import DATABASE_URI
Base = declarative_base()
metadata = Base.metadata
class Portfolio(Base):
__tablename__ = 'Portfolios'
Portfolio = Column(CHAR(4), primary_key=True)
GUID = Column(CHAR(36), nullable=False)
def get_df(session):
q = session.query(Portfolio)
return pd.read_sql(q.statement, q.session.bind)
class TickerDatum(Base):
__tablename__ = 'TickerData'
Ticker = Column(String(8), primary_key=True, nullable=False, server_default=text("''"))
TS_Name = Column(String(100), primary_key=True, nullable=False, server_default=text("''"))
TS_Type = Column(CHAR(1), primary_key=True, nullable=False)
TS_Index = Column(String(10), primary_key=True, nullable=False, server_default=text("''"))
Value = Column(DECIMAL(15, 4))
Note = Column(String(255))
def get_df(session):
q = session.query(TickerDatum)
return pd.read_sql(q.statement, q.session.bind)
class Transaction(Base):
__tablename__ = 'Transactions'
TransID = Column(INTEGER(11), primary_key=True)
TransDate = Column(DateTime, nullable=False)
Portfolio = Column(CHAR(4))
Ticker = Column(String(20))
ShareType = Column(CHAR(1), comment='(S)Share, (B)ond')
TransType = Column(CHAR(1), nullable=False, comment='(B)uy, (S)ell, (D)ividend, (W)ithdraw, d(E)posit, s(P)lit, (I)inlösen')
NoShares = Column(DECIMAL(15, 5))
PerShare = Column(DECIMAL(15, 2))
Amount = Column(DECIMAL(15, 2), nullable=False, comment='should equal NoShares x PerShare x sign')
Courtage = Column(DECIMAL(15, 2), nullable=False)
TransAmount = Column(DECIMAL(15, 2), nullable=False, comment='should equal Amount + Courtage')
Currency = Column(CHAR(3), nullable=False)
Depo = Column(String(20))
Note = Column(String(255))
def get_df(session):
q = session.query(Transaction)
return pd.read_sql(q.statement, q.session.bind)
# codegen don't generate a class for this table since it doesn't have a primary key
t_StockOwnership = Table(
'StockOwnership', metadata,
Column('Portfolio', CHAR(4), nullable=False),
Column('Ticker', String(8), nullable=False),
Column('Period', INTEGER(6), nullable=False, comment="YYYYQQ, set QQ=00 for full year when if quarterly data isn't saved"),
Column('NoShares', DECIMAL(15, 0), nullable=False),
Column('EPS', DECIMAL(15, 2), nullable=False),
Column('DPS', DECIMAL(15, 2), nullable=False),
Column('Earnings', DECIMAL(15, 0), nullable=False, comment='EPS x NoShares'),
Column('RetainedEarnings', DECIMAL(15, 0), nullable=False, comment='(EPS-DPS) x NoShares'),
Column('Dividends', DECIMAL(15, 0), nullable=False, comment='DPS x NoShares'),
Index('Ticker', 'Ticker', 'Portfolio', 'Period', unique=True)
)
def get_stock_ownership_df(session):
q = session.query(t_StockOwnership)
return pd.read_sql(q.statement, q.session.bind)
engine = create_engine(DATABASE_URI)
session = sessionmaker()
session.configure(bind=engine)
s = session()
print(Portfolio.get_df(s))
print(get_stock_ownership_df(s))
print(Transaction.get_df(s))
Run the app:
python invest.py