def run(self, canvas_api_domain, api_key): app.logger.info(f'New poller running for {canvas_api_domain}') api_url = f'https://{canvas_api_domain}' self.canvas = get_canvas(api_url, api_key) while True: course = db.session.query(Course) \ .filter_by(canvas_api_domain=canvas_api_domain, active=True) \ .order_by(nullsfirst(Course.last_polled.asc())) \ .with_for_update() \ .first() if not course: app.logger.info(f'No active courses found, poller exiting: {canvas_api_domain}') break app.logger.info(f"Will poll {_format_course(course)}, last polled {course.last_polled or 'never'}") course.last_polled = datetime.now() db.session.add(course) std_commit() try: self.poll_course(course) except Exception as e: app.logger.error(f'Failed to poll course {_format_course(course)}') app.logger.exception(e) sleep(5)
def nulls_first(col, session: Session) -> Dict[str, Any]: """ Adds a nullsfirst construct to the column ordering. Currently only Postgres supports it. In MySQL & Sqlite NULL values are considered lower than any non-NULL value, therefore, NULL values appear first when the order is ASC (ascending) """ if session.bind.dialect.name == "postgresql": return nullsfirst(col) else: return col
def _order_by(self, query, joins, sort_joins, sort_field, sort_desc): """ Apply order_by to the query :param query: Query :pram joins: Current joins :param sort_joins: Sort joins (properties or tables) :param sort_field: Sort field :param sort_desc: Select sort order: * True: for descending order * False or None: for ascending default order * 'LAST': for NULLS LAST * 'FIRST': for NULLS FIRST """ if sort_field is not None: # Handle joins query, joins, alias = self._apply_path_joins(query, joins, sort_joins, inner_join=False) column = sort_field if alias is None else getattr( alias, sort_field.key) if sort_desc is True: if isinstance(column, tuple): query = query.order_by(*map(desc, column)) else: query = query.order_by(desc(column)) elif sort_desc is False: if isinstance(column, tuple): query = query.order_by(*column) else: query = query.order_by(column) elif sort_desc == 'LAST': query = query.order_by(nullslast(desc(column))) elif sort_desc == 'FIRST': query = query.order_by(nullsfirst(desc(column))) return query, joins
async def select_fetch_task(session: sqlalchemy.ext.asyncio.AsyncSession, subscribers: Iterable[str] ) -> Union[None, Tuple[int, int, None, None], Tuple[int, int, None, int], Tuple[int, int, int, int]]: stmt = (sqlalchemy.union_all( sqlalchemy.select( Channel.guild_id, ChannelState.channel_id, sqlalchemy.cast(sqlalchemy.null(), sqlalchemy.BigInteger).label("thread_id"), sqlalchemy.null().label("before_snowflake")) .join(ChannelState.channel) .where(Channel.reachable, ChannelState.subscriber.in_(subscribers), ChannelState.earliest_thread_archive_ts != None) .order_by(ChannelState.earliest_thread_archive_ts.desc()) .limit(1), sqlalchemy.select( Channel.guild_id, ChannelRequest.channel_id, sqlalchemy.null().label("thread_id"), ChannelRequest.before_snowflake) .join(ChannelRequest.state) .join(ChannelState.channel) .where(Channel.reachable, ChannelRequest.subscriber.in_(subscribers)) .order_by(ChannelRequest.before_snowflake.desc()) .limit(1), sqlalchemy.select( Channel.guild_id, ThreadRequest.channel_id, ThreadRequest.thread_id, ThreadRequest.before_snowflake) .join(ThreadRequest.state) .join(ChannelState.channel) .where(Channel.reachable, ThreadRequest.subscriber.in_(subscribers)) .order_by(ThreadRequest.before_snowflake.desc()) .limit(1)) .order_by(sqlalchemy.nullsfirst(sqlalchemy.literal_column("before_snowflake").desc())) .limit(1)) row = (await session.execute(stmt)).first() if row is None: return None guild_id, channel_id, thread_id, before = row return guild_id, channel_id, thread_id, before
def list_reviewer(language_id, sort_key, order): """List of reviewers applying filters and sorting""" reviewers = ( Reviewer.query.outerjoin( ReviewRequest, Reviewer.id == ReviewRequest.reviewer_id ) .add_columns( Reviewer.id.label("id"), Reviewer.first_name.label("first_name"), Reviewer.last_name.label("last_name"), func.count(ReviewRequest.id).label("review_count"), func.max(ReviewRequest.review_date).label("last_review"), ) .group_by(Reviewer.id, Reviewer.first_name, Reviewer.last_name) ) if language_id: reviewers = reviewers.filter( Reviewer.languages.any(ReviewLanguage.id == language_id) ) sorting = { "asc": lambda x: nullsfirst(asc(x)), "desc": lambda x: nullslast(desc(x)), }[order] return reviewers.order_by(sorting(sort_key)).all()
}, endpoint=short_name) api.add_resource(CharacterResourceList, '/characters/<int:character_id>/{}'.format(name), resource_class_kwargs={ 'type': type, 'order': order, 'fields': fields }, endpoint=name) information_fields = {'name': str, 'description': str, 'group': str} add_character_resource(api, 'info', 'information', m.Information, (nullsfirst(asc('group')), 'name'), information_fields) variable_fields = {'name': str, 'value': int} add_character_resource(api, 'variable', 'variables', m.Variable, 'name', variable_fields) roll_fields = {'name': str, 'expression': str, 'group': str} add_character_resource(api, 'roll', 'rolls', m.Roll, (nullsfirst(asc('group')), 'name'), roll_fields) resource_fields = {'name': str, 'current': int, 'max': int, 'recover': m.Rest} add_character_resource(api, 'resource', 'resources', m.Resource, 'name', resource_fields) spell_fields = { 'name': str,