diff --git a/Examples/Sample.py b/Examples/Sample.py index e0a315f..891b764 100644 --- a/Examples/Sample.py +++ b/Examples/Sample.py @@ -17,13 +17,13 @@ #connect to database # createconnection (dbtype, servername, dbname, username, password) # session_factory = dbconnection.createConnection('connection type: sqlite|mysql|mssql|postgresql', '/your/path/to/db/goes/here', 2.0)#sqlite -session_factory = dbconnection.createConnection('postgresql', 'localhost', 'odm2', 'ODM', 'odm') -# session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm')#mysql -# session_factory= dbconnection.createConnection('mssql', "(local)", "ODM2", "ODM", "odm")#win MSSQL +# session_factory = dbconnection.createConnection('postgresql', 'localhost', 'odm2', 'ODM', 'odm') +# session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm')#mysql +session_factory= dbconnection.createConnection('mssql', "(local)", "ODM2", "ODM", "odm")#win MSSQL # session_factory= dbconnection.createConnection('mssql', "arroyoodm2", "", "ODM", "odm")#mac/linux MSSQL -# session_factory = dbconnection.createConnection('sqlite', '/Users/stephanie/DEV/YODA-Tools/tests/test_files/XL_specimen.sqlite', 2.0) +# session_factory = dbconnection.createConnection('sqlite', 'path/to/ODM2.sqlite', 2.0) @@ -61,6 +61,7 @@ try: print ("\n-------- Information about Sites ---------") siteFeatures = read.getSamplingFeatures(type= 'site') + # siteFeatures = read.getSamplingFeatures(type='Site') numSites = len(siteFeatures) print ("Successful query") @@ -144,7 +145,7 @@ # Get the values for a particular TimeSeriesResult print("\n-------- Example of Retrieving Time Series Result Values ---------") -tsValues = read.getResultValues(resultid = 1) # Return type is a pandas datafram +tsValues = read.getResultValues(resultids = [1]) # Return type is a pandas datafram # Print a few Time Series Values to the console # tsValues.set_index('ValueDateTime', inplace=True) diff --git a/odm2api/ODM2/services/readService.py b/odm2api/ODM2/services/readService.py index 78ba586..0d105cc 100644 --- a/odm2api/ODM2/services/readService.py +++ b/odm2api/ODM2/services/readService.py @@ -614,8 +614,8 @@ def getAffiliations(self, ids=None, personfirst=None, personlast=None, orgcode=N return None # Results - def getResults(self, ids=None, type=None, uuids=None, actionid=None, simulationid=None, sfid=None, - variableid=None, siteid=None): + def getResults(self, ids=None, type=None, restype = None, uuids=None, actionid=None, simulationid=None, sfid=None, + variableid=None, siteid=None, sfids=None, sfuuids=None, sfcodes=None): # TODO what if user sends in both type and actionid vs just actionid """Retrieve a list of Result objects. @@ -625,7 +625,7 @@ def getResults(self, ids=None, type=None, uuids=None, actionid=None, simulationi Args: ids (list, optional): List of ResultIDs. - type (str, optional): Type of Result from + restype (str, optional): Type of Result from `controlled vocabulary name `_. uuids (list, optional): List of UUIDs string. actionid (int, optional): ActionID. @@ -634,14 +634,17 @@ def getResults(self, ids=None, type=None, uuids=None, actionid=None, simulationi variableid (int, optional): VariableID. siteid (int, optional): SiteID. - goes through related features table and finds all of results recorded at the given site + sfids(list, optional): List of Sampling Feature IDs integer. + sfuuids(list, optional): List of Sampling Feature UUIDs string. + sfcodes=(list, optional): List of Sampling Feature codes string. Returns: list: List of Result objects Examples: >>> ReadODM2.getResults(ids=[39,40]) - >>> ReadODM2.getResults(type='Time series coverage') - >>> ReadODM2.getResults(sfid=65) + >>> ReadODM2.getResults(restype='Time series coverage') + >>> ReadODM2.getResults(sfids=[65]) >>> ReadODM2.getResults(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) >>> ReadODM2.getResults(simulationid=50) @@ -653,7 +656,12 @@ def getResults(self, ids=None, type=None, uuids=None, actionid=None, simulationi query = self._session.query(Results) if type: + import warnings + warnings.warn( + "The parameter 'type' is no longer be supported. Please use the restype parameter instead.") query = query.filter_by(ResultTypeCV=type) + if restype: + query = query.filter_by(ResultTypeCV=restype) if variableid: query = query.filter_by(VariableID=variableid) if ids: @@ -668,9 +676,18 @@ def getResults(self, ids=None, type=None, uuids=None, actionid=None, simulationi if actionid: query = query.join(FeatureActions).filter_by(ActionID=actionid) if sfid: + import warnings + warnings.warn("The parameter 'sfid' is no longer be supported. Please use the sfids parameter and send in a list.") query = query.join(FeatureActions).filter_by(SamplingFeatureID=sfid) + if sfids or sfcodes or sfuuids: + sf_list = self.getSamplingFeatures(ids=sfids, codes=sfcodes, uuids=sfuuids) + sfids = [] + for sf in sf_list: + sfids.append(sf.SamplingFeatureID) + query = query.join(FeatureActions).filter(FeatureActions.SamplingFeatureID.in_(sfids)) if siteid: + sfids = [x[0] for x in self._session.query( distinct(SamplingFeatures.SamplingFeatureID)) .select_from(RelatedFeatures) @@ -678,6 +695,13 @@ def getResults(self, ids=None, type=None, uuids=None, actionid=None, simulationi .filter(RelatedFeatures.RelatedFeatureID == siteid) .all() ] + + #TODO does this code do the same thing as the code above? + # sf_list = self.getRelatedSamplingFeatures(rfid=siteid) + # sfids = [] + # for sf in sf_list: + # sfids.append(sf.SamplingFeatureID) + query = query.join(FeatureActions).filter(FeatureActions.SamplingFeatureID.in_(sfids)) try: diff --git a/tests/test_odm2/test_readservice.py b/tests/test_odm2/test_readservice.py index a2ce719..120c23d 100644 --- a/tests/test_odm2/test_readservice.py +++ b/tests/test_odm2/test_readservice.py @@ -76,7 +76,7 @@ def setup(self): self.db = globals_vars['db'] -# Sampling Features + # Sampling Features def test_getAllSamplingFeatures(self): # get all models from the database res = self.engine.execute('SELECT * FROM SamplingFeatures').fetchall() @@ -91,6 +91,14 @@ def test_getSamplingFeatureByID(self): # get all simulations using the api resapi = self.reader.getSamplingFeatures(ids=[sfid]) assert resapi is not None + + def test_getSamplingFeatureByCode(self): + # get all models from the database + res = self.engine.execute('SELECT * FROM SamplingFeatures').fetchone() + code = res[2] + # get all simulations using the api + resapi = self.reader.getSamplingFeatures(codes=[code]) + assert resapi is not None #DataSets def test_getDataSets(self): @@ -121,8 +129,6 @@ def test_getDataSetsValues(self): assert len(values) > 0 - - #ToDo figure out how to actually test this function def test_getSamplingFeatureDataSets(self): #find a sampling feature that is associated with a dataset @@ -151,18 +157,48 @@ def test_getSamplingFeatureDataSets(self): assert len(dsapi) > 0 assert ds[1] == dsapi[0].DataSetID + # Results + def test_getAllResults(self): + # get all results from the database + res = self.engine.execute('SELECT * FROM Results').fetchall() + print(res) + # get all results using the api + resapi = self.reader.getResults() + assert len(res) == len(resapi) -# Models - """ - TABLE Models - ModelID INTEGER NOT NULL PRIMARY KEY, - ModelCode VARCHAR (50) NOT NULL, - ModelName VARCHAR (255) NOT NULL, - ModelDescription VARCHAR (500) NULL, - Version VARCHAR (255) NULL, - ModelLink VARCHAR (255) NULL - """ + def test_getResultsByID(self): + # get a result from the database + res = self.engine.execute('SELECT * FROM Results').fetchone() + resultid = res[1] + + # get the result using the api + resapi = self.reader.getResults(ids=[resultid]) + assert resapi is not None + def test_getResultsBySFID(self): + sf = self.engine.execute( + 'SELECT * from SamplingFeatures as sf ' + 'inner join FeatureActions as fa on fa.SamplingFeatureID == sf.SamplingFeatureID ' + 'inner join Results as r on fa.FeatureActionID == r.FeatureActionID ' + ).fetchone() + assert len(sf) > 0 + sfid = sf[0] + + res = self.engine.execute( + 'SELECT * from Results as r ' + 'inner join FeatureActions as fa on fa.FeatureActionID == r.FeatureActionID ' + 'where fa.SamplingFeatureID = ' + str(sfid) + ).fetchone() + + assert len(res) > 0 + + # get the result using the api + resapi = self.reader.getResults(sfids=[sfid]) + assert resapi is not None + assert len(resapi) > 0 + assert resapi[0].ResultID == res[0] + + # Models def test_getAllModels(self): # get all models from the database res = self.engine.execute('SELECT * FROM Models').fetchall() @@ -179,19 +215,7 @@ def test_getModelByCode(self): assert resapi is not None -# RelatedModels - """ - TABLE RelatedModels ( - RelatedID INTEGER NOT NULL PRIMARY KEY, - ModelID INTEGER NOT NULL, - RelationshipTypeCV VARCHAR (255) NOT NULL, - RelatedModelID INTEGER NOT NULL, - FOREIGN KEY (RelationshipTypeCV) REFERENCES CV_RelationshipType (Name) - ON UPDATE NO ACTION ON DELETE NO ACTION, - FOREIGN KEY (ModelID) REFERENCES Models (ModelID) - ON UPDATE NO ACTION ON DELETE NO ACTION - """ - + # RelatedModels def test_getRelatedModelsByID(self): # get related models by id using the api resapi = self.reader.getRelatedModels(id=1) @@ -214,61 +238,7 @@ def test_getRelatedModelsByCode(self): # test invalid argument resapi = self.reader.getRelatedModels(code=234123) assert not resapi - - -# Results - """ - TABLE Results ( - ResultID INTEGER NOT NULL PRIMARY KEY, - ResultUUID VARCHAR(36) NOT NULL, - FeatureActionID INTEGER NOT NULL, - ResultTypeCV VARCHAR (255) NOT NULL, - VariableID INTEGER NOT NULL, - UnitsID INTEGER NOT NULL, - TaxonomicClassifierID INTEGER NULL, - ProcessingLevelID INTEGER NOT NULL, - ResultDateTime DATETIME NULL, - ResultDateTimeUTCOffset INTEGER NULL, - ValidDateTime DATETIME NULL, - ValidDateTimeUTCOffset INTEGER NULL, - StatusCV VARCHAR (255) NULL, - SampledMediumCV VARCHAR (255) NOT NULL, - ValueCount INTEGER NOT NULL - """ - def test_getAllResults(self): - # get all results from the database - res = self.engine.execute('SELECT * FROM Results').fetchall() - # print(res) - # get all results using the api - resapi = self.reader.getResults() - assert len(res) == len(resapi) - - def test_getResultsByID(self): - # get a result from the database - res = self.engine.execute('SELECT * FROM Results').fetchone() - resultid = res[1] - - # get the result using the api - resapi = self.reader.getResults(ids=[resultid]) - assert resapi is not None - # Simulations - """ - TABLE Simulations ( - SimulationID INTEGER NOT NULL PRIMARY KEY, - ActionID INTEGER NOT NULL, - SimulationName VARCHAR (255) NOT NULL, - SimulationDescription VARCHAR (500) NULL, - SimulationStartDateTime DATETIME NOT NULL, - SimulationStartDateTimeUTCOffset INTEGER NOT NULL, - SimulationEndDateTime DATETIME NOT NULL, - SimulationEndDateTimeUTCOffset INTEGER NOT NULL, - TimeStepValue FLOAT NOT NULL, - TimeStepUnitsID INTEGER NOT NULL, - InputDataSetID INTEGER NULL, - ModelID INTEGER NOT NULL, - """ - def test_getAllSimulations(self): # get all simulation from the database res = self.engine.execute('SELECT * FROM Simulations').fetchall()