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.

88 lines
2.4 KiB
Python

from configparser import ConfigParser
import bcrypt
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean, Numeric
from sqlalchemy.orm import relationship, backref
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.types import DateTime as DateTimeType
cfg = ConfigParser()
cfg.read('config.ini')
BCRYPT_LOG_ROUNDS = cfg.get('user', 'BCRYPT_LOG_ROUNDS')
# can be moved to models util?
class utcnow(expression.FunctionElement):
type = DateTimeType()
# Can be moved to the models util?
@compiles(utcnow, 'postgresql')
def pg_utcnow(element, compiler, **kw):
return "TIMEZONE('utc', CURRENT_TIMESTAMP)"
Base = declarative_base()
class DBMixin:
id = Column(Integer, 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__
d.pop('_sa_instance_state')
return d
def ReferenceCol(tablename, nullable=False, **kw):
return Column(ForeignKey('{}.id'.format(tablename)), nullable=nullable, **kw)
class Cookie(Base, DBMixin):
__tablename__ = 'cookies'
name = Column(String(50), index=True)
recipe_url = Column(String(255))
sku = Column(String(55))
qoh = Column(Integer)
unit_cost = Column(Numeric(12, 2))
class User(DBMixin, Base):
__tablename__ = 'users'
email = Column(String(255), nullable=False, unique=True)
password = Column(String(255))
admin = Column(Boolean, nullable=False, default=False)
def __init__(self, email, password, admin=False):
self.email = email
self.password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt(BCRYPT_LOG_ROUNDS)).decode()
self.admin = admin
class Order(DBMixin, Base):
__tablename__ = 'orders'
user_id = ReferenceCol('users')
shipped = Column(Boolean, default=False)
user = relationship('User', backref=backref('orders'))
class LineItem(DBMixin, Base):
__tablename__ = 'line_items'
order_id = ReferenceCol('orders')
cookie_id = ReferenceCol('cookies')
quantity = Column(Integer)
extended_cost = Column(Numeric(12, 2))
order = relationship('Order', backref=backref('line_items'))
cookie = relationship('Cookie', uselist=False)