def _get_existing_database(self, database_id: int, schema: str = None) -> Database: """Returns the database object for an existing database Keyword arguments: database_id -- the ID used to identify the database schema -- the schema to be used Raises: SchemaNotAllowedCsvUploadException: If the schema is not allowed for csv upload GetDatabaseException: 1. If the database ID is not valid 2. If there was a problem getting the schema NoResultFound: If no database found with id MultipleResultsFound: If more than one database found with id """ try: database = db.session.query(Database).filter_by( id=database_id).one() if not self._is_schema_allowed_for_csv_upload(database, schema): message = _( f"Database {database.database_name} Schema {schema} is not allowed for csv uploads. " "Please contact your Superset administrator.") raise SchemaNotAllowedCsvUploadException(message, None) return database except NoResultFound as e: raise NoResultFound("Database was not found.", e) except MultipleResultsFound as e: raise MultipleResultsFound("Multiple databases were found.", e) except SchemaNotAllowedCsvUploadException as e: raise e except Exception as e: raise GetDatabaseException( "An unknown error occurred trying to get the database.", e)
def test013_load_from_ext_id_multiple(self): m_session = MagicMock() external_id = "whatever" m_filter = m_session.query().options().filter m_filter.side_effect = MultipleResultsFound() with self.assertRaises(IrmaDatabaseError): Scan.load_from_ext_id(external_id, m_session)
def one(self) -> Any: if len(self._result) == 1: return self._result[0] elif self._result: raise MultipleResultsFound("Multiple rows returned for one()") else: raise NoResultFound("No rows returned for one()")
def createUser(self, username): """ Creates a new entry for new usernames, if a user is found with this email that has not yet registered, just returns that user's ID. Raises an exception if multiple results found, or if user has already registered. Arguments: username - username to find or create an id for Returns: user object """ # Check if user exists queryResult = self.session.query(User).options(joinedload("user_status")).filter(User.username == username).all() if(len(queryResult) == 1): # If so, check their status user = queryResult[0] if(user.user_status.name == "awaiting_confirmation" or user.user_status.name == "email_confirmed"): # User has not yet registered, may restart process return user elif(len(queryResult) == 0): # If not, add new user newUser = User(username = username) self.session.add(newUser) self.session.commit() return newUser else: # Multiple entries for this user, server error raise MultipleResultsFound("Multiple entries for single username")
def _insert_url(session, url): """ insert into table Page if not exist and return the url id Args: url(str): wiki url to update Returns: int: url id Raise: DisconnectionError MultipleResultsFound """ try: if session.query(Page.id).filter_by(url=url).scalar() is None: page = Page(url=url) session.add(page) session.commit() url_id = session.query(Page).filter_by(url=url).first().id _insert_link(session, url_id, url_id, 0) except DisconnectionError: raise DisconnectionError("There is error with DB connection") except MultipleResultsFound: raise MultipleResultsFound("Many rows found in DB to find url \ id of {}".format(url)) url_id = session.query(Page.id).filter_by(url=url).first() return url_id.id
def find_or_create(cls, session, namespace_id, name, display_name, type_): name = name or '' objects = session.query(cls).filter( cls.namespace_id == namespace_id, cls.display_name == display_name).all() if not objects: obj = cls(namespace_id=namespace_id, name=name, display_name=display_name, type_=type_, deleted_at=EPOCH) session.add(obj) elif len(objects) == 1: obj = objects[0] if not obj.name: # There is an existing category with this `display_name` and no # `name`, so update it's `name` as needed. # This is needed because the first time we sync generic IMAP # folders, they may initially have `name` == '' but later they may # get a `name`. At this point, it *is* the same folder so we # merely want to update its `name`, not create a new one. obj.name = name else: log.error('Duplicate category rows for namespace_id {}, ' 'name {}, display_name: {}'.format( namespace_id, name, display_name)) raise MultipleResultsFound( 'Duplicate category rows for namespace_id {}, name {}, ' 'display_name: {}'.format(namespace_id, name, display_name)) return obj
def lookup(session, model, **attrs): """ Find a unique object identified by a set of attributes. :param session: An SQLAlchemy session :param model: An SQLAlchemy model to find :param attrs: A set of column names and values to use for matching. """ conditions = tuple(getattr(model, attr) == attrs[attr] for attr in attrs) filter_cond = and_(*conditions) query = session.query(model).filter(filter_cond) num = query.count() if num == 1: obj = query.first() logger.debug('found %r object %r', model, obj) return obj elif num == 0: raise NoResultFound("No results for %r with condition %r" % (model, filter_cond)) else: raise MultipleResultsFound( "Multiple results (%d) for %r with condition %r" % (num, model, filter_cond))
def test_classmethod_load_from_sha256_raise_MultipleResultNotFound(self): # nopep8 sample = "test" session = MagicMock() session.query.side_effect = MultipleResultsFound(sample) with self.assertRaises(IrmaDatabaseError) as context: module.File.load_from_sha256("whatever", session) self.assertEqual(str(context.exception), sample)
def scalar(self) -> Any: if len(self._result) == 1: row = self._result[0] return row[0] elif self._result: raise MultipleResultsFound( "Multiple rows were found when exactly one was required") return None
def is_run(filename): migration = SESSION.query(SchemaMigration).filter( SchemaMigration.migration_file == filename) if migration.count() > 1: raise MultipleResultsFound( 'Multiple migration files found with specified name.') return migration.first().run_status
def one_or_none(self) -> Optional[Any]: if len(self._result) == 1: return self._result[0] elif self._result: raise MultipleResultsFound( "Multiple rows returned for one_or_none()") else: return None
def find_one(cls, **kwargs): result = cls.find(**kwargs) if not result: raise NoResultFound("No {} found for query:{}".format(cls.__name__, kwargs)) elif len(result) > 1: raise MultipleResultsFound("More than one {} found for query:{}".format(cls.__name__, kwargs)) else: return result[0]
def search(lcid): try: query = sessions[lcid].query(Type) if search_word.isdigit(): types = query.filter_by(id=search_word) else: types = query.filter(Type.name.contains(search_word)) update_results2description(lcid, types.one()) except MultipleResultsFound: if types.count() > config.search_limit: raise MultipleResultsFound() else: html = '' groups = collections.OrderedDict() list_lorder = lorder.load('list.html') for type_ in types.all(): group = type_.group if group not in groups: groups[group] = [] if lcid == config.default_lcid: groups[group].append(type_) else: default_type = sessions[config.default_lcid].query(Type) \ .filter_by(id=type_.id).one() groups[group].append(default_type) for group, types_ in groups.items(): name = group.name try: locale_group = sessions[config.lcid].query(Group) \ .filter_by(id=group.id).one() name = '%s(%s)' % (locale_group.name, group.name) except: pass kwargs = { 'name': name, 'items': create_list_items(Type, types_, '/type/'), } html += tornado.escape.to_basestring( list_lorder.generate(kwargs=update_template_kwargs(kwargs)) ) html += '<hr />' results['content'] = html results['name'] = search_word results['search_word'] = search_word except NoResultFound: return False return True
def get_scalar(rows: Sequence[Any]) -> Any: """Utility for mocking sqlalchemy.orm.Query.scalar().""" if len(rows) == 1: try: return rows[0][0] except TypeError: return rows[0] elif len(rows) > 1: raise MultipleResultsFound( "Multiple rows were found when exactly one was required" ) return None
def get(cls, id): try: result = db_session.query(cls).filter_by(id=id).one() except MultipleResultsFound: msg = 'There are multiple {} records with the same id={}!'.format(cls.__name__, id) log.critical(msg) raise MultipleResultsFound(msg) except NoResultFound: msg = 'There is no record {} with id={}!'.format(cls.__name__, id) log.debug(msg) raise NoResultFound(msg) else: return result
def find_by_name(cls, name): try: result = db_session.query(cls).filter_by(name=name).one() except MultipleResultsFound: # Theoretically cannot happen because of model built-in constraints msg = 'Multiple command segments with identical names has been found!' log.critical(msg) raise MultipleResultsFound(msg) except NoResultFound: msg = 'There is no command segment with name={}!'.format(name) log.warning(msg) raise NoResultFound(msg) else: return result
def checkUserInDb(self, request, claims): idUser = claims.get('sub') query = request.dbsession.query( TUsers.TUse_PK_ID, TUsers.TUse_LastName, TUsers.TUse_FirstName, TUsers.TUse_CreationDate, TUsers.TUse_Login, TUsers.TUse_Language, TUsers.TUse_ModificationDate, TUsers.TUse_HasAccess, TUsers.TUse_Photo, TUsers.TUse_PK_ID_OLD) query = query.filter(TUsers.TUse_PK_ID == idUser) try: res = query.one_or_none() return TUsersSchema().dump(res) if res else None except MultipleResultsFound: raise MultipleResultsFound() return res
def update_row_by_id(session: Session, model: DeclarativeMeta, id: int, updates: dict): """ update the fields of a row with the particular primary key Parameters ---------- session sqlalchemy.orm.session.Session session object to be used model sqlalchemy.ext.declarative.DeclarativeMeta the sqlalchemy model to use id int the primary key updates dict the fields to update as the keys and their respective values and the dictionary values """ if not isinstance(updates, dict): raise TypeError('updates must be of type dict') query = read_row_by_id(session, model, id) try: query.one() except NoResultFound as e: raise NoResultFound( f"row cannot be updated because no row can be found with id: {id}") except MultipleResultsFound as e: raise MultipleResultsFound( f"the database contains multiple results for this id when only one is expected. id: {id}" ) matched = query.update(updates) if matched == 0: raise ValueError( f"bad update request, no columns could be matched updates requested: {json.dumps(updates)}" ) try: session.commit() session.flush() except Exception as e: session.rollback() session.flush() raise e
def test_multiple_product_groups(self, User): from sqlalchemy.orm.exc import MultipleResultsFound user = mock.Mock() user.id = 1 user.email = '*****@*****.**' p = mock.PropertyMock(side_effect=MultipleResultsFound('Boom!')) type(user).product_group = p User.get_all.return_value = [ user, ] from pyramid_bimt.sanitycheck import CheckUsersProductGroup self.assertEqual( CheckUsersProductGroup()(), ['User [email protected] (1) has multiple product groups.'], )
def find_one(cls, **kwargs): ''' Wrapper of find() that return a single result. Will error if None or more then one results found. ''' result = cls.find(**kwargs) if not result: raise NoResultFound("No {} found for query:{}".format( cls.__name__, kwargs)) elif len(result) > 1: raise MultipleResultsFound( "More than one {} found for query:{}".format( cls.__name__, kwargs)) else: return result[0]
def get_ori_identifier(self, iri): """ Retrieves a Resource-based ORI identifier from the database. If no corresponding Resource exists, a new one is created. """ session = self.Session() try: resource = session.query(Resource).join(Source).filter( Source.iri == iri).one() return Uri(Ori, resource.ori_id) except MultipleResultsFound: raise MultipleResultsFound('Multiple resources found for IRI %s' % iri) except NoResultFound: return self.generate_ori_identifier(iri=iri) finally: session.close()
def get_category_by_name(session, name): ''' Get the category matching a name. - Category name can be a simple name, or a full path to a category inside the Category hierarchy. - A full path consists of a sequence of category names separated by '->' e.g. 'Refined->Gasoline' ''' full_path = name.split('->') if len(full_path) > 1: # traverse the path try: cat_obj = (session.query(Category).filter( Category.name == full_path[0]).filter( Category.parent == None).one()) for cat_name in full_path[1:]: matching_catlist = [ c for c in cat_obj.children if c.name == cat_name ] if len(matching_catlist) > 1: raise MultipleResultsFound('One matching child Category ' 'required, found {} categories ' 'matching the name {}'.format( len(matching_catlist), cat_name)) elif len(matching_catlist) == 0: raise NoResultFound('child Category matching the name {} ' 'not found'.format(cat_name)) cat_obj = matching_catlist[0] except Exception: cat_obj = None else: # just a simple name try: cat_obj = (session.query(Category).filter( Category.name == name).one()) except Exception: cat_obj = None return cat_obj
def get_mergeable_resource_identifier(self, model_object, predicate, column, value): """ Queries the database to find the ORI identifier of the Resource linked to the Property with the given predicate and value in the specified column. """ definition = model_object.definition(predicate) session = self.Session() try: query_result = session.query(Property).filter( Property.predicate == definition.absolute_uri()) if column == 'prop_resource': query_result = query_result.filter( Property.prop_resource == value) elif column == 'prop_string': query_result = query_result.filter( Property.prop_string == value) elif column == 'prop_datetime': query_result = query_result.filter( Property.prop_datetime == value) elif column == 'prop_integer': query_result = query_result.filter( Property.prop_integer == value) elif column == 'prop_url': query_result = query_result.filter(Property.prop_url == value) else: raise ValueError( 'Invalid column type "%s" specified for merge_into' % column) resource_property = query_result.one() return resource_property.resource.iri except MultipleResultsFound: raise MultipleResultsFound( 'Multiple resources found for predicate "%s" with value "%s" in column "%s"' % (predicate, value, column)) except NoResultFound: raise NoResultFound( 'No resource found for predicate "%s" with value "%s" in column "%s"' % (predicate, value, column)) finally: session.close()
def get_rov_sol(cls, roverparam, sol): """Return photo data for a given Rover and mission sol.""" try: rover = DBSession.query(Rover).filter_by(name=roverparam).one() except NoResultFound: raise NoResultFound("Invalid rover name") except MultipleResultsFound: raise MultipleResultsFound("How did you even do that?") return_dict = {} # finds absolute last day in which this rover has photos. maxsol_tuple = DBSession.query(func.max( Photo.sol)).filter(Photo.rover_name == roverparam).one() maxsol = maxsol_tuple[0] if not maxsol: raise ValueError("No photos for your rover in database") if sol > maxsol: sol = maxsol while sol < maxsol: if rover.photos.filter(Photo.sol == sol).first(): break sol += 1 return_dict['rover'] = rover.name return_dict['sol'] = sol return_dict['photos_by_cam'] = {} return_dict['last_day'] = True if sol >= maxsol else False return_dict['first_day'] = True if sol <= 1 else False for cam in rover.cameras: photos_query = cam.photos.filter(Photo.sol == sol) photos_query = filter_only_left(photos_query, roverparam) photos_query = filter_bad_quality(photos_query, roverparam) photos_query = order_photo_query(photos_query) return_dict['photos_by_cam'][cam.name] = photos_query.all() return return_dict
def fetch_all_first_values(session: Session, select_statement: Select) -> List[Any]: """ Returns a list of the first values in each row returned by a ``SELECT`` query. A Core version of this sort of thing: http://xion.io/post/code/sqlalchemy-query-values.html Args: session: SQLAlchemy :class:`Session` object select_statement: SQLAlchemy :class:`Select` object Returns: a list of the first value of each result row """ rows = session.execute(select_statement) # type: ResultProxy try: return [row[0] for row in rows] except ValueError as e: raise MultipleResultsFound(str(e))
def test_take_action_multiple(self, m_dev_obj): # remove ShowOne from the DeviceShow inheritance bases = copy(ds.DeviceShow.__bases__) f_bases = tuple(base for base in bases if base != ShowOne) m_args = mock.Mock() m_args._get_kwargs.return_value = {'detailed': None} m_dev_obj.find.side_effect = MultipleResultsFound() m_base = mock.patch.object(ds.DeviceShow, '__bases__', f_bases) with m_base: m_base.is_local = True t_device = dss.DeviceShowSerial() t_device.app = mock.Mock() self.assertRaises(RuntimeWarning, t_device.take_action, m_args) # ensure that is_local on the patch does not modify the actual bases self.assertEqual(bases, ds.DeviceShow.__bases__)
def _insert_link(session, from_page_id, to_page_id, no_of_separation): """ insert link into database if link is not existed Args: from_page_id(int): id of "from" page to_page_id(int): id of "to" page no_of_separation(int) Returns: None Raise DisconnectionError MultipleResultsFound """ try: if session.query(Link).filter_by( from_page_id=from_page_id, to_page_id=to_page_id, number_of_separation=no_of_separation).scalar() is None: link = Link(from_page_id=from_page_id, to_page_id=to_page_id, number_of_separation=no_of_separation) session.add(link) session.commit() except DisconnectionError: raise DisconnectionError("There is error with DB connection") except MultipleResultsFound: raise MultipleResultsFound( "Many rows found in DB to store link from {} to {}\ with number of seperation {}".format(from_page_id, to_page_id, no_of_separation))
def get_or_create(session, model, **attrs): """ Find or create a unique object identified by a set of attributes. .. note:: Created objects are not added to the database session, so this function is is really only useful if you *know* you're going to mutate the result. Otherwise you'll have to check the object state to figure out if it needs to be added to the database session (https://docs.sqlalchemy.org/en/latest/orm/session_state_management.html), and at that point it might be easier to *not* use this function. :param session: An SQLAlchemy session :param model: An SQLAlchemy model to find :param attrs: A set of column names and values to use for matching. If a matching object is not found, it will be created using these values. """ conditions = tuple(getattr(model, attr) == attrs[attr] for attr in attrs) filter_cond = and_(*conditions) query = session.query(model).filter(filter_cond) num = query.count() if num == 0: obj = model(**attrs) logger.debug('created new %r object %r', model, obj) return obj elif num == 1: obj = query.first() logger.debug('found existing %r object %r', model, obj) return obj else: raise MultipleResultsFound( "Multiple results (%d) for %r with condition %r" % (num, model, filter_cond))
mock_update_notification_status.assert_called_with(notification, notify_status) def test_govdelivery_callback_returns_200( client, mock_dao_get_notification_by_reference, mock_map_govdelivery_status_to_notify_status, mock_update_notification_status, ): response = post(client, get_govdelivery_request("123456", "sent")) assert response.status_code == 200 @pytest.mark.parametrize("exception", [MultipleResultsFound(), NoResultFound()]) def test_govdelivery_callback_always_returns_200_after_expected_exceptions( client, mock_dao_get_notification_by_reference, mock_map_govdelivery_status_to_notify_status, mock_update_notification_status, exception ): mock_dao_get_notification_by_reference.side_effect = exception response = post(client, get_govdelivery_request("123456", "sent")) assert response.status_code == 200 def test_govdelivery_callback_raises_invalid_request_if_missing_data(client):
class TestProcessSNSDeliveryStatus: @pytest.mark.skip(reason="Endpoint disabled and slated for removal") @pytest.mark.parametrize('data', [ payload_with_missing_message_id(), payload_with_missing_status(), get_sns_delivery_status_payload(create_uuid(), "NOT_A_VALID_STATE"), get_sns_delivery_status_payload("not-uuid", SNS_STATUS_SUCCESS) ]) def test_returns_bad_request_on_schema_validation_errors( self, client, data): response = post(client, data) assert response.status_code == 400 @pytest.mark.skip(reason="Endpoint disabled and slated for removal") def test_loads_notification_by_reference( self, client, mock_notification, mock_dao_get_notification_by_reference, mock_update_notification_status, mock_process_service_callback): mock_dao_get_notification_by_reference.return_value = mock_notification post( client, get_sns_delivery_status_payload(mock_notification.reference, SNS_STATUS_SUCCESS)) mock_dao_get_notification_by_reference.assert_called_with( mock_notification.reference) @pytest.mark.skip(reason="Endpoint disabled and slated for removal") @pytest.mark.parametrize( "exception", [MultipleResultsFound(), NoResultFound()]) def test_returns_404_when_unable_to_load_notification( self, client, mock_notification, mock_dao_get_notification_by_reference, exception): mock_dao_get_notification_by_reference.side_effect = exception response = post( client, get_sns_delivery_status_payload(mock_notification.reference, SNS_STATUS_SUCCESS)) assert response.status_code == 404 @pytest.mark.skip(reason="Endpoint disabled and slated for removal") @pytest.mark.parametrize("sns_status, status", [(SNS_STATUS_SUCCESS, NOTIFICATION_SENT), (SNS_STATUS_FAILURE, NOTIFICATION_FAILED)]) def test_should_update_notification_status( self, client, mock_notification, mock_dao_get_notification_by_reference, mock_update_notification_status, mock_process_service_callback, sns_status, status): mock_dao_get_notification_by_reference.return_value = mock_notification post( client, get_sns_delivery_status_payload(mock_notification.reference, sns_status)) mock_update_notification_status.assert_called_with( mock_notification, status) @pytest.mark.skip(reason="Endpoint disabled and slated for removal") def test_should_process_service_callback( self, client, mock_notification, mock_dao_get_notification_by_reference, mock_update_notification_status, mock_process_service_callback, ): mock_dao_get_notification_by_reference.return_value = mock_notification mock_update_notification_status.return_value = mock_notification post( client, get_sns_delivery_status_payload(mock_notification.reference, SNS_STATUS_SUCCESS)) mock_process_service_callback.assert_called_with(mock_notification) @pytest.mark.skip(reason="Endpoint disabled and slated for removal") def test_should_send_callback_metrics( self, client, mock_notification, mock_dao_get_notification_by_reference, mock_update_notification_status, mock_process_service_callback, mock_send_callback_metrics): mock_dao_get_notification_by_reference.return_value = mock_notification mock_update_notification_status.return_value = mock_notification post( client, get_sns_delivery_status_payload(mock_notification.reference, SNS_STATUS_SUCCESS)) mock_send_callback_metrics.assert_called_with(mock_notification) @pytest.mark.skip(reason="Endpoint disabled and slated for removal") def test_returns_204( self, client, mock_notification, mock_dao_get_notification_by_reference, mock_update_notification_status, mock_process_service_callback, ): mock_dao_get_notification_by_reference.return_value = mock_notification mock_update_notification_status.return_value = mock_notification response = post( client, get_sns_delivery_status_payload(mock_notification.reference, SNS_STATUS_SUCCESS)) assert response.status_code == 204