class Provider(Model): """ .base.Model provides: id (primary key) created_at (creation date) .appointment.Appointment.Model provides appointments (through secondary table) """ records = db.relationship('Record', backref='provider', lazy=True) userprofile_id = db.Column(db.Integer, db.ForeignKey('userprofile.id')) userprofile = db.relationship("UserProfile", back_populates='provider') manager_id = db.Column(db.Integer, db.ForeignKey('manager.id')) active = db.Column(db.Boolean, default=False)
class Manager(Model): """ .base.Model provides: id (primary key) created_at (creation date) .address.Address.Model provides: addresses (collection through secondary table) """ userprofile_id = db.Column(db.Integer, db.ForeignKey('userprofile.id')) userprofile = db.relationship("UserProfile", back_populates='manager') schedulers = db.relationship('Scheduler', backref='manager', lazy=True) providers = db.relationship('Provider', backref='manager', lazy=True) active = db.Column(db.Boolean, default=False)
class Record(Model): """ Base Model Provides: id (primary key) created_at (creation date) """ patron_id = db.Column(db.Integer, db.ForeignKey('patron.id'), nullable=False) measurements = db.relationship('Measurement', backref='measurements', lazy=True) appointment_id = db.Column(db.Integer, db.ForeignKey('appointment.id')) provider_id = db.Column(db.Integer, db.ForeignKey('provider.id')) def __repr__(self): return f'<Record {self.id} ' \ f'patron_id: {self.patron_id} ' \ f'provider_id: {self.provider_id} ' \ f'appointment_id: {self.appointment_id}>' @property def measurements(self): return Measurement.query.filter(Measurement.record_id == self.id) \ .order_by(Measurement.created_at) @property def measurements_serialized(self): return [measurement.dictionary for measurement in self.measurements] @property def number_of_measurements(self): return self.measurements.count() @property def dictionary(self): return { 'id': self.id, 'created_at': self.created_at, 'patron': self.patron.dicrionary, 'provider': self.provider.dictionary, 'measurement_count': self.number_of_measurements, 'measurements': self.measurements_serialized, 'appointment': self.appointment, }
class Measurement(Model): """ Base Model Provides: id (primary key) created_at (creation date) """ name = db.Column(db.String(256), nullable=False) description = db.Column(db.String(2000), nullable=True) value = db.Column(db.String(256), nullable=False) units = db.Column(db.String(256), nullable=False) valid = db.Column(db.Boolean, nullable=False, default=True) record_id = db.Column(db.Integer, db.ForeignKey('record.id'), nullable=False) def __repr__(self): return f'<Measurement {self.id} with record_id: {self.record_id} value: {self.value} units: {self.units}>' @property def dictionary(self): return { 'id': self.id, 'created_at': self.created_at, 'name': self.name, 'description': self.description, 'value': self.value, 'units': self.units, 'valid': self.valid, 'record_id': self.record.id, }
class Patron(Model): """ .base.Model provides: id (primary key) created_at (creation date) """ records = db.relationship('Record', backref='patron', lazy=True) # 1 to many userprofile_id = db.Column(db.Integer, db.ForeignKey('userprofile.id')) userprofile = db.relationship("UserProfile", back_populates='patron') def __repr__(self): return f'<Patron {self.id}: user_id: {self.user}>' @property def dictionary(self): return { 'id': self.id, 'created_at': str(self.created_at.to(TIMEZONE)), 'records': self.id, 'userprofile_id': self.userprofile_id, 'userprofile': self.userprofile.dictionary, }
class Appointment(Model): """ .base.Model provides: id (primary key) created_at (creation date) """ name = db.Column(db.String(256), nullable=False) records = db.relationship('Record', backref='appointment', lazy=True) confirmed = db.Column(db.Boolean, default=False, nullable=False) held = db.Column(db.Boolean, default=False, nullable=False) cancelled = db.Column(db.Boolean, default=False, nullable=False) scheduler_id = db.Column(db.Integer, db.ForeignKey('scheduler.id'), nullable=False) address_id = db.Column(db.Integer, db.ForeignKey('address.id')) providers = db.relationship("Provider", secondary=provider_appointment_association_table, backref="appointments") @declared_attr def start_time(self): return db.Column(ArrowType, default=utcnow, nullable=False, index=True) def __repr__(self): return f'<Appointment {self.id} with start_time: {self.start_time.isoformat()}>' @property def all_records(self): return Record.query.filter(Record.appointment_id == self.id) \ .order_by(Record.created_at) @property def all_records_serialized(self): return [record.dictionary for record in self.all_records] @property def dictionary(self): return { 'id': self.id, 'created_at': self.created_at, 'name': self.name, 'address': self.address.dictionary, 'start_time': self.start_time.isoformat(), 'confirmed': self.confirmed, 'cancelled': self.cancelled, 'held': self.held, 'records': self.all_records_serialized, }
class Address(Model): """ Base Model Provides: id (primary key) created_at (creation date) """ nickname = db.Column(db.String(), nullable=False) line1 = db.Column(db.String(), nullable=False) line2 = db.Column(db.String(), nullable=True) city = db.Column(db.String(), nullable=False) state = db.Column(db.String(), nullable=False) zip_code = db.Column(db.String(), nullable=False) user_profiles = db.relationship("UserProfile", secondary=user_address_association_table, backref="addresses") schedulers = db.relationship("Scheduler", secondary=scheduler_address_association_table, backref="addresses") managers = db.relationship("Manager", secondary=manager_address_association_table, backref="addresses") appointments = db.relationship("Appointment", backref="address") def __repr__(self): return f'<Address {self.id}>' @property def dictionary(self): return { 'id': self.id, 'created_at': self.created_at.isoformat(), 'line1': self.line1, 'line2': self.line2, 'city' : self.city, 'state': self.state, 'zip_code': self.zip_code, 'user_profiles': self.all_users #'appointments': self.all_appointments todo upcoming and past appointments } @property def all_users_serialized(self): data = list() for user in self.user_profiles: data.append(user.nickname) return data
class UserProfile(UserMixin, Model): """ .base.Model provides: id (primary key) created_at (creation date) flask_login.UserMixin provides: .address.Address.Model provides: addresses (collection) .record.Record.Model provides: records (collection) """ alternate_id = db.Column(db.String(256), nullable=False, unique=True) social_id = db.Column(db.String(256), nullable=True, unique=True) nickname = db.Column(db.String(256), nullable=True) email = db.Column(db.String(256), nullable=True) picture = db.Column(db.String(256), nullable=True) name = db.Column(db.String(256), nullable=True) family_name = db.Column(db.String(256), nullable=True) given_name = db.Column(db.String(256), nullable=True) locale = db.Column(db.String(16), default='en', nullable=False) updated_at = db.Column(ArrowType, default=utcnow, index=True) email_verified = db.Column(db.Boolean, nullable=True, default=False) patron = db.relationship('Patron', uselist=False, back_populates="userprofile") # 1-to-1 provider = db.relationship('Provider', uselist=False, back_populates="userprofile") # 1-to-1 scheduler = db.relationship('Scheduler', uselist=False, back_populates="userprofile") # 1-to-1 manager = db.relationship('Manager', uselist=False, back_populates="userprofile") # 1-to-1 def __repr__(self): return f'<User {self.id}: email: {self.email} nickname: {self.nickname}>' @property def dictionary(self): return { 'id': self.id, 'created_at': str(self.created_at.to(TIMEZONE)), 'alternate_id': self.alternate_id, 'social_id': self.social_id, 'email': self.email, 'email_verified': self.email_verified, 'name': self.name, 'family_name': self.family_name, 'given_name': self.given_name, 'locale': self.locale, 'updated_at': str(self.updated_at.to(TIMEZONE)), 'my_patron_id': self.patron.id, 'my_provider_id': self.provider.id, 'my_scheduler_id': self.scheduler.id, 'my_manager_id': self.manager.id } @property def all_records(self): return [] @property def all_records_serialized(self): return [] @classmethod def get_or_create(cls, sub): existing_user = cls.query.filter(cls.alternate_id == sub).one_or_none() if existing_user: return existing_user else: new_user = cls(alternate_id=sub) new_user.save() patron = Patron(userprofile=new_user, userprofile_id=new_user.id) patron.save() new_user.patron = patron new_user.save() provider = Provider(userprofile=new_user, userprofile_id=new_user.id) provider.save() new_user.provider = provider new_user.save() manager = Manager(userprofile=new_user, userprofile_id=new_user.id) manager.save() new_user.manager = manager new_user.save() scheduler = Scheduler(userprofile=new_user, userprofile_id=new_user.id) scheduler.save() new_user.scheduler = scheduler new_user.save() return new_user
from .base import Model from mymed.db import db __all__ = ('Address',) user_address_association_table = db.Table('user_address_association', Model.metadata, db.Column('address_id', db.Integer, db.ForeignKey('address.id')), db.Column('userprofile_id', db.Integer, db.ForeignKey('userprofile.id')), ) scheduler_address_association_table = db.Table('scheduler_address_association', Model.metadata, db.Column('address_id', db.Integer, db.ForeignKey('address.id')), db.Column('scheduler_id', db.Integer, db.ForeignKey('scheduler.id')), ) manager_address_association_table = db.Table('manager_address_association', Model.metadata, db.Column('address_id', db.Integer, db.ForeignKey('address.id')), db.Column('manager_id', db.Integer, db.ForeignKey('manager.id')), ) class Address(Model): """ Base Model Provides: id (primary key) created_at (creation date) """ nickname = db.Column(db.String(), nullable=False) line1 = db.Column(db.String(), nullable=False)
def created_at(cls): return db.Column(ArrowType, default=utcnow, nullable=False, index=True)
class Model(db.Model, QueryMixin): """Abstract base class for all app models. Provides an `id` & `created_at` column to every model. To define models, follow this example: from .base import Model class MyModel(Model): # model definition """ __abstract__ = True id = db.Column(db.Integer, primary_key=True) @declared_attr def created_at(cls): return db.Column(ArrowType, default=utcnow, nullable=False, index=True) @property def class_name(self): """Shortcut for returning class name.""" return unicode(self.__class__.__name__) @classmethod def __ignore__(cls): """Custom class attr that lets us control which models get ignored. We are using this because knowing whether or not we're actually dealing with an abstract base class is only possible late in the class's init lifecycle. This is used by the dynamic model loader to know if it should ignore. """ return cls.__name__ in ('Model', ) # can add more abstract base classes here def __repr__(self): """"Returns a string representation of every object. Useful for logging & error reporting. Example: >>> obj = MyModel() >>> print obj MyModel.123 Can be overridden by subclasses to customize string representation. """ return u"{}.{}".format(self.class_name, self.id) @declared_attr def __tablename__(cls): """Generate a __tablename__ attr for every model that does not have inherited tables. Ensures table names match the model name without needing to declare it. """ if has_inherited_table(cls): return None return cls.__name__.lower()
def start_time(self): return db.Column(ArrowType, default=utcnow, nullable=False, index=True)
from arrow import utcnow from sqlalchemy_utils import ArrowType from sqlalchemy.ext.declarative import declared_attr from .base import Model from .record import Record from mymed.db import db __all__ = ('Appointment',) provider_appointment_association_table = db.Table('provider_appointment_association', Model.metadata, db.Column('provider_id', db.Integer, db.ForeignKey('provider.id')), db.Column('appointment_id', db.Integer, db.ForeignKey('appointment.id')), ) class Appointment(Model): """ .base.Model provides: id (primary key) created_at (creation date) """ name = db.Column(db.String(256), nullable=False) records = db.relationship('Record', backref='appointment', lazy=True) confirmed = db.Column(db.Boolean, default=False, nullable=False) held = db.Column(db.Boolean, default=False, nullable=False) cancelled = db.Column(db.Boolean, default=False, nullable=False) scheduler_id = db.Column(db.Integer, db.ForeignKey('scheduler.id'), nullable=False) address_id = db.Column(db.Integer, db.ForeignKey('address.id'))