def query_db(self): ''' This is ran every <interval> milliseoncds. We refresh the humanized dates in the reminder due column and we check if any reminders are due Note that sqlalchemy session in this thread is not the same session as in the main thread. The scoped_session ensures in one thread we can keep a kind of global session. It saves passing around copies of the same session to different places, but it does not ensure same session between threads. We need to be careful that changes to db in this thread don't break other thread changes etc. Using sessions just for the duration of work and not eternal sessions that get init during __init__ of main window and worker thread is also essential This ensures the sessions are fresh and not out of date with db after changes by the other thread...This is also consider good practice see http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#when-do-i-construct-a-session-when-do-i-commit-it-and-when-do-i-close-it In this app, we can simply restrict this worker to only reading the db and never writing to it. We can set the complete=True after the signal in the main thread ''' # Use this loop to also refresh the human dates (e.g. "In 1 hour" in table) self.refresh_human_dates.emit() reminders = [] with session_scope() as session: reminders = session.query(Reminder).filter( Reminder.complete == False).filter( func.DATETIME(Reminder.due, 'utc') <= func.DATETIME( 'now', 'utc')).all() logger.debug('Got %i reminders due...' % len(reminders)) for reminder in reminders: self.reminderisdue.emit(str(reminder.reminder_id))
def date_gt(item: QueryableAttribute, expected: datetime): if isinstance(item.property.columns[0].type, sqltypes.Date): # that's because FHIR spec states that, if the date is e.g 1985-10-12 and the queried value is # 1985-10-12T10:00:00 than 1985-10-12 shall be included return date_ge(item, expected) else: return func.DATETIME(item) > func.DATETIME(expected)
def date_ap(item: QueryableAttribute, expected: datetime): """ Date is approximately equal. Approximately means at discretion of the implementation. Here for dates we set approximation between one day before and one day after the required value :param item: :param expected: :return: """ delta = timedelta(days=1) if isinstance(item.property.columns[0].type, sqltypes.Date): return between(func.DATE(item), func.DATE(expected - delta), func.DATE(expected + delta)) else: return between(func.DATETIME(item), func.DATETIME(expected - delta), func.DATETIME(expected + delta))
def get(): models = None if "sqlite" in os.environ.get("DATABASE_URI"): models = Appointment.query.filter( func.DATETIME(Appointment.end) >= datetime.datetime.now()).all() else: models = Appointment.query.filter( cast(Appointment.end, DateTime) >= datetime.datetime.now()).all() appointments = [] for model in models: appointments.append(model.toDict()) return {"data": appointments}, 200
def get_upcoming_fixtures_by_league(self, league_id, limit=-1): """Gets the next Fixture entities which are yet to be played for the given league. Args: league_id (int): The id of a League entity to match. limit (int): How many results to retrieve. Returns: list: All Fixture entities which are yet to be played for the given league. """ with self.session_scope() as session: return (session.query(Fixture).filter_by( league_id=league_id).filter( func.DATETIME(Fixture.date) >= datetime.now()).order_by( Fixture.date).limit(limit).all())
def date_le(item: QueryableAttribute, expected: datetime): if isinstance(item.property.columns[0].type, sqltypes.Date): return func.DATE(item) <= func.DATE(expected) else: return func.DATETIME(item) <= func.DATETIME(expected)