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 # 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) 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' username = Column(String(255), nullable=False, unique=True) email_address = Column(String(255), nullable=False) phone = Column(String(20), nullable=False) password = Column(String(255)) 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)