diff --git a/.travis.yml b/.travis.yml index 38b7453..680088e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,8 +39,6 @@ matrix: - python: 3.6 env: TEST_TARGET=docs allow_failures: - - python: 2.7 - env: TEST_TARGET=coding_standards - python: 3.6 env: TEST_TARGET=default diff --git a/README.md b/README.md index 19ec59c..32a1dff 100644 --- a/README.md +++ b/README.md @@ -38,17 +38,17 @@ source activate myenv # On MacOSX or Linux but they haven't been tested thoroughly. -### Latest release, from ODM2 anaconda.org channel +### Latest release, from conda-forge anaconda.org channel The [latest `odm2api` release](https://github.com/ODM2/ODM2PythonAPI/releases) is available on the -[ODM2 anaconda.org channel](https://anaconda.org/odm2/odm2api) +[conda-forge anaconda.org channel](https://anaconda.org/conda-forge/odm2api) for all major OS paltforms (linux, OSX, win32/win64). To install it on an existing conda environment: ``` -conda install -c odm2 odm2api +conda install -c conda-forge odm2api ``` All dependencies are installed, @@ -57,33 +57,38 @@ including Pandas and its dependencies (numpy, etc). To create a new environment "myenv" with the `odm2api` package: ``` -conda create -n myenv -c odm2 python=2.7 odm2api +conda create -n myenv -c conda-forge python=2.7 odm2api ``` -### Installing the development version from the `master` branch on github - -**Note from 4/26/2016:** These instructions may be slightly outdated. -Follow these directions for installing the bleeding edge GitHub master branch, -mainly for development and testing purposes. - -To create a new environment "myenv" with `odm2api`, -first download the conda environment file -[condaenvironment_1.yml](https://raw.githubusercontent.com/ODM2/ODM2PythonAPI/master/condaenvironment_1.yml). -Go to the directory where `condaenvironment_1.yml` was downloaded. -Then, on a terminal shell: - -```bash -conda env create -n myenv --file py2_conda_environment.yml -``` - -Activate the new environment, then install `odm2api` into the environment: - -```bash -activate myenv # On Windows -source activate myenv # On MacOSX or Linux - -pip install --process-dependency-links git+https://github.com/ODM2/ODM2PythonAPI.git -``` +### Installing the development version from the `development` branch on github + +Note: We follow the [Gitflow workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) for development. + +1. Download both `requirements.txt` and `requirements-dev.txt`. + ``` bash + wget https://raw.githubusercontent.com/ODM2/ODM2PythonAPI/master/requirements.txt + wget https://raw.githubusercontent.com/ODM2/ODM2PythonAPI/master/requirements-dev.txt + ``` + +2. Create conda environment `odm2api_dev` from the two `requirements*` text files. + ```bash + conda create -n odm2api_dev -c conda-forge python=2.7 --file requirements.txt --file requirements-dev.txt + ``` + +3. Activate conda environment. + - MacOSX/Linux: + ```bash + source activate odm2api_dev + ``` + - Windows: + ``` + activate odm2api_dev + ``` + +4. Install the latest commit from the development branch + ```bash + pip install git+https://github.com/ODM2/ODM2PythonAPI.git@development#egg=odm2api + ``` ## Credits diff --git a/docs/source/installing.rst b/docs/source/installing.rst index a135c24..4064f0f 100644 --- a/docs/source/installing.rst +++ b/docs/source/installing.rst @@ -12,7 +12,7 @@ OS X and Linux, it's something like To activate a conda environment, say, "myenv": -.. code:: bash +.. code-block:: bash activate myenv # On Windows source activate myenv # On MacOSX or Linux @@ -21,17 +21,17 @@ To activate a conda environment, say, "myenv": changes have been made to support Python 3.x, but they haven't been tested thoroughly. -Latest release, from ODM2 anaconda.org channel +Latest release, from conda-forge anaconda.org channel ---------------------------------------------- -The `latest release `__ is available -on the `ODM2 anaconda.org channel `__ +The `latest release `_ is available +on the `conda-forge anaconda.org channel `_ for all major OS platforms (linux, OS X, win32/win64). To install it on an existing conda environment: :: - conda install odm2api --channel odm2 + conda install -c conda-forge odm2api All dependencies are installed, including Pandas and its dependencies (numpy, etc). @@ -40,23 +40,42 @@ To create a new environment "myenv" with the ``odm2api`` package: :: - conda create -n myenv -c odm2 python=2.7 odm2api + conda create -n myenv -c conda-forge python=2.7 odm2api -Installing the development version +Installing the development version from the ``development`` branch on github ---------------------------------- -To create a new environment "myenv" with ``odm2api``, first clone the repository. -Then, on a terminal shell: - -.. code:: bash - - conda create --name myenv python=2.7 --file requirements.txt --file requirements-dev.txt -c odm2 - -Activate the new environment, then install ``odm2api`` into the -environment: - -.. code:: bash - - activate myenv # On Windows - source activate myenv # On OS X or Linux +Note: We follow the `Gitflow workflow `__ for development. + +1. Download both ``requirements.txt`` and ``requirements-dev.txt``. + + .. code-block:: bash + + wget https://raw.githubusercontent.com/ODM2/ODM2PythonAPI/master/requirements.txt + wget https://raw.githubusercontent.com/ODM2/ODM2PythonAPI/master/requirements-dev.txt + +2. Create conda environment ``odm2api_dev`` from the two ``requirements*`` text files. + + .. code-block:: bash + + conda create -n odm2api_dev -c conda-forge python=2.7 --file requirements.txt --file requirements-dev.txt + +3. Activate conda environment. + - MacOSX/Linux: + + .. code-block:: bash + + source activate odm2api_dev + + - Windows: + + .. code-block:: bash + + activate odm2api_dev + +4. Install the latest commit from the development branch + + .. code-block:: bash + + pip install git+https://github.com/ODM2/ODM2PythonAPI.git@development#egg=odm2api diff --git a/docs/source/models.rst b/docs/source/models.rst index bd5bb0a..aa23167 100644 --- a/docs/source/models.rst +++ b/docs/source/models.rst @@ -12,16 +12,16 @@ The following are entities in the `ODM2 Core Schema = startdate) - if dates: - q = q.filter(TimeSeriesResultValues.ValueDateTime.in_(dates)) - numvals = q.count() - q.delete(False) - return numvals +def DeleteODM2(*args, **kwargs): + warnings.warn('The class odm2api.ODM2.services.readService.DeleteODM2 will be deprecated. ' + 'Please use odm2api.services.readService.DeleteODM2 instead.', + FutureWarning, stacklevel=2) + return newClass(*args, **kwargs) diff --git a/odm2api/ODM2/services/readService.py b/odm2api/ODM2/services/readService.py index cbe8cc4..177f784 100644 --- a/odm2api/ODM2/services/readService.py +++ b/odm2api/ODM2/services/readService.py @@ -2,1498 +2,18 @@ import warnings -from odm2api.ODM2 import serviceBase -from odm2api.ODM2.models import ( - ActionAnnotations, ActionDirectives, ActionExtensionPropertyValues, Actions, - Affiliations, Annotations, AuthorLists, CVActionType, CVAggregationStatistic, - CVAnnotationType, CVCensorCode, CVDataQualityType, CVDataSetType, CVDirectiveType, - CVElevationDatum, CVEquipmentType, CVMediumType, CVMethodType, CVOrganizationType, - CVPropertyDataType, CVQualityCode, CVRelationshipType, CVResultType, CVSamplingFeatureGeoType, - CVSamplingFeatureType, CVSiteType, CVSpatialOffsetType, CVSpeciation, CVSpecimenType, - CVStatus, CVTaxonomicClassifierType, CVUnitsType, CVVariableName, CVVariableType, - CalibrationActions, CalibrationReferenceEquipment, CalibrationStandards, - CategoricalResultValueAnnotations, CategoricalResultValues, CitationExtensionPropertyValues, - CitationExternalIdentifiers, DataLoggerFileColumns, DataLoggerFiles, DataLoggerProgramFiles, - DataQuality, DataSetCitations, DataSets, DataSetsResults, DerivationEquations, Directives, Equipment, - EquipmentActions, EquipmentAnnotations, EquipmentModels, EquipmentUsed, ExtensionProperties, - ExternalIdentifierSystems, FeatureActions, InstrumentOutputVariables, MaintenanceActions, - MeasurementResultValueAnnotations, MeasurementResultValues, MethodAnnotations, - MethodCitations, MethodExtensionPropertyValues, MethodExternalIdentifiers, - Methods, Models, Organizations, People, PersonExternalIdentifiers, - PointCoverageResultValueAnnotations, PointCoverageResultValues, ProcessingLevels, - ProfileResultValueAnnotations, ProfileResultValues, ReferenceMaterialExternalIdentifiers, - ReferenceMaterialValues, ReferenceMaterials, RelatedActions, RelatedAnnotations, - RelatedCitations, RelatedDataSets, RelatedEquipment, RelatedFeatures, RelatedModels, - RelatedResults, ResultAnnotations, ResultDerivationEquations, ResultExtensionPropertyValues, - ResultNormalizationValues, Results, ResultsDataQuality, SamplingFeatureAnnotations, - SamplingFeatureExtensionPropertyValues, SamplingFeatureExternalIdentifiers, - SamplingFeatures, SectionResultValueAnnotations, SectionResults, Simulations, - SpatialReferenceExternalIdentifiers, SpatialReferences, SpecimenBatchPositions, - SpectraResultValueAnnotations, SpectraResultValues, TaxonomicClassifierExternalIdentifiers, - TaxonomicClassifiers, TimeSeriesResultValueAnnotations, TimeSeriesResultValues, - TrajectoryResultValueAnnotations, TrajectoryResultValues, - TransectResultValueAnnotations, TransectResultValues, Units, VariableExtensionPropertyValues, - VariableExternalIdentifiers, Variables, -) +from odm2api.services.readService import ReadODM2 as newClass -import pandas as pd +warnings.warn('The module odm2api.ODM2.services.readService will be deprecated. ' + 'Please use odm2api.services.readService instead.', + FutureWarning, stacklevel=2) -from sqlalchemy import distinct, exists __author__ = 'sreeder' -class DetailedResult: - def __init__(self, action, result, - sc, sn, - method, variable, - processingLevel, - unit): - # result.result_id etc. - self.ResultID = result.ResultID - self.SamplingFeatureCode = sc - self.MethodCode = method.MethodCode - self.VariableCode = variable.VariableCode - self.ProcessingLevelCode = processingLevel.ProcessingLevelCode - self.UnitsName = unit.UnitsName - - self.SamplingFeatureName = sn - self.MethodName = method.MethodName - self.VariableNameCV = variable.VariableNameCV - self.ProcessingLevelDefinition = processingLevel.Definition - self.ValueCount = result.ValueCount - self.BeginDateTime = action.BeginDateTime - self.EndDateTime = action.EndDateTime - self.ResultObj = result - - -class DetailedAffiliation: - def __init__(self, affiliation, person, org): - self.AffiliationID = affiliation.AffiliationID - self.Name = person.PersonFirstName + ' ' + person.PersonLastName - self.Organization = '(' + org.OrganizationCode + ') ' + org.OrganizationName - - -class SamplingFeatureDataSet(): - datasets = {} - related_features = {} - - def __init__(self, samplingfeature, datasetresults, relatedfeatures): - sf = samplingfeature - - self.SamplingFeature = sf - self.SamplingFeatureID = sf.SamplingFeatureID - self.SamplingFeatureUUID = sf.SamplingFeatureUUID - self.SamplingFeatureTypeCV = sf.SamplingFeatureTypeCV - self.SamplingFeatureCode = sf.SamplingFeatureCode - self.SamplingFeatureName = sf.SamplingFeatureName - self.SamplingFeatureDescription = sf.SamplingFeatureDescription - self.SamplingFeatureGeotypeCV = sf.SamplingFeatureGeotypeCV - self.Elevation_m = sf.Elevation_m - self.ElevationDatumCV = sf.ElevationDatumCV - self.FeatureGeometryWKT = sf.FeatureGeometryWKT - self.assignDatasets(datasetresults) - self.assignRelatedFeatures(relatedfeatures) - - print(self.datasets) - - def assignDatasets(self, datasetresults): - self.datasets = {} - if datasetresults: - for dsr in datasetresults: - if dsr.DataSetObj not in self.datasets: - # if the dataset is not in the dictionary, add it and the first result - self.datasets[dsr.DataSetObj] = [] - res = dsr.ResultObj - # res.FeatureActionObj = None - self.datasets[dsr.DataSetObj].append(res) - else: - # if the dataset is in the dictionary, append the result object to the list - res = dsr.ResultObj - # res.FeatureActionObj = None - self.datasets[dsr.DataSetObj].append(res) - - def assignRelatedFeatures(self, relatedfeatures): - self.related_features = {} - if relatedfeatures: - for related in relatedfeatures: - if related.SamplingFeatureTypeCV == 'Site': - self.related_features = related - - -class ReadODM2(serviceBase): - def _get_columns(self, model): - """Internal helper function to get a dictionary of a model column properties. - - Args: - model (object): Sqlalchemy object, Ex. ODM2 model. - - Returns: - dict: Dictionary of column properties Ex. {'resultid': 'ResultID'} - - """ - from sqlalchemy.orm.properties import ColumnProperty - columns = [(prop.key.lower(), prop.key) for prop in model.__mapper__.iterate_properties if - isinstance(prop, ColumnProperty)] - - return dict(columns) - - def _check_kwargs(self, args, kwargs): - """Internal helper function to check for unused keyword arguments - - Args: - args (list): List of expected, valid arguments. - kwargs (dict): Dictionary of keyword arguments from user - Returns: - None - """ - invkwd = filter(lambda x: x not in args, kwargs.keys()) - if invkwd: - warnings.warn('Got unexpected keyword argument(s) {}'.format(','.join(invkwd)), stacklevel=2) - - # Exists functions - def resultExists(self, result): - """ - Check to see if a Result Object exists - * Pass Result Object - return a boolean value of wether the given object exists - - """ - try: - - ret = self._session.query(exists().where(Results.ResultTypeCV == result.ResultTypeCV) - .where(Results.VariableID == result.VariableID) - .where(Results.UnitsID == result.UnitsID) - .where(Results.ProcessingLevelID == result.ProcessingLevelID) - .where(Results.SampledMediumCV == result.SampledMediumCV) - ) - return ret.scalar() - - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Annotations - def getAnnotations(self, annottype=None, codes=None, ids=None, **kwargs): - """ - * Pass Nothing - return a list of all objects - * Pass AnnotationTypeCV - return a list of all objects of the fiven type - * Pass a list of codes - return a list of objects, one for each of the given codes - * Pass a list of ids -return a list of objects, one for each of the given ids - - """ - # TODO What keywords do I use for type. - a = Annotations - self._check_kwargs(['type'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the annottype parameter instead.', - DeprecationWarning, stacklevel=2) - annottype = kwargs['type'] - if annottype: - if annottype == 'action': - a = ActionAnnotations - elif annottype == 'categoricalresultvalue': - a = CategoricalResultValueAnnotations - elif annottype == 'equipmentannotation': - a = EquipmentAnnotations - elif annottype == 'measurementresultvalue': - a = MeasurementResultValueAnnotations - elif annottype == 'method': - a = MethodAnnotations - elif annottype == 'pointcoverageresultvalue': - a = PointCoverageResultValueAnnotations - elif annottype == 'profileresultvalue': - a = ProfileResultValueAnnotations - elif annottype == 'result': - a = ResultAnnotations - elif annottype == 'samplingfeature': - a = SamplingFeatureAnnotations - elif annottype == 'sectionresultvalue': - a = SectionResultValueAnnotations - elif annottype == 'spectraresultvalue': - a = SpectraResultValueAnnotations - elif annottype == 'timeseriesresultvalue': - a = TimeSeriesResultValueAnnotations - elif annottype == 'trajectoryresultvalue': - a = TrajectoryResultValueAnnotations - elif annottype == 'transectresultvalue': - a = TransectResultValueAnnotations - try: - query = self._session.query(a) - if codes: - query = query.filter(Annotations.AnnotationCode.in_(codes)) - if ids: - query = query.filter(Annotations.AnnotationID.in_(ids)) - return query.all() - - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # CV - def getCVs(self, cvtype, **kwargs): - """ - getCVs(self, type): - * Pass CVType - return a list of all objects of the given type - - """ - self._check_kwargs(['type'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the cvtype parameter instead.', - DeprecationWarning, stacklevel=2) - cvtype = kwargs['type'] - - if cvtype == 'actiontype': - CV = CVActionType - elif cvtype == 'aggregationstatistic': - CV = CVAggregationStatistic - elif cvtype == 'annotationtype': - CV = CVAnnotationType - elif cvtype == 'censorcode': - CV = CVCensorCode - elif cvtype == 'dataqualitytype': - CV = CVDataQualityType - elif cvtype == 'dataset type': - CV = CVDataSetType - elif cvtype == 'Directive Type': - CV = CVDirectiveType - elif cvtype == 'Elevation Datum': - CV = CVElevationDatum - elif cvtype == 'Equipment Type': - CV = CVEquipmentType - elif cvtype == 'Medium': - CV = CVMediumType - elif cvtype == 'Method Type': - CV = CVMethodType - elif cvtype == 'Organization Type': - CV = CVOrganizationType - elif cvtype == 'Property Data Type': - CV = CVPropertyDataType - elif cvtype == 'Quality Code': - CV = CVQualityCode - elif cvtype == 'Relationship Type': - CV = CVRelationshipType - elif cvtype == 'Result Type': - CV = CVResultType - elif cvtype == 'Sampling Feature Geo-type': - CV = CVSamplingFeatureGeoType - elif cvtype == 'Sampling Feature Type': - CV = CVSamplingFeatureType - elif cvtype == 'Site Type': - CV = CVSiteType - elif cvtype == 'Spatial Offset Type': - CV = CVSpatialOffsetType - elif cvtype == 'Speciation': - CV = CVSpeciation - elif cvtype == 'Specimen Type': - CV = CVSpecimenType - elif cvtype == 'Status': - CV = CVStatus - elif cvtype == 'Taxonomic Classifier Type': - CV = CVTaxonomicClassifierType - elif cvtype == 'Units Type': - CV = CVUnitsType - elif cvtype == 'Variable Name': - CV = CVVariableName - elif cvtype == 'Variable Type': - CV = CVVariableType - else: - return None - try: - return self._session.query(CV).all() - except Exception as e: - print('Error running Query: {}'.format(e)) - - # Core - def getDetailedAffiliationInfo(self): - """ - * Pass Nothing - Return a list of all Affiliations with detailed information, - including Affiliation, People and Organization - - """ - q = self._session.query(Affiliations, People, Organizations) \ - .filter(Affiliations.PersonID == People.PersonID) \ - .filter(Affiliations.OrganizationID == Organizations.OrganizationID) - affiliationList = [] - for a, p, o in q.all(): - detailedAffiliation = DetailedAffiliation(a, p, o) - affiliationList.append(detailedAffiliation) - return affiliationList - - def getDetailedResultInfo(self, resultTypeCV=None, resultID=None, sfID=None): - # TODO can this be done by just getting the result object and drilling down? - # What is the performance comparison. - """ - Get detailed information for all selected Results including , unit info, site info, - method info , ProcessingLevel info. - * Pass nothing - return a list of all objects - * Pass resultTypeCV - All objects of given type - * Pass a result ID - single object with the given result ID - * Pass a SamplingFeatureID - All objects associated with the given sampling feature. - - """ - q = self._session.query( - Actions, - Results, - SamplingFeatures.SamplingFeatureCode, - SamplingFeatures.SamplingFeatureName, - Methods, - Variables, - ProcessingLevels, - Units).filter(Results.VariableID == Variables.VariableID) \ - .filter(Results.UnitsID == Units.UnitsID) \ - .filter(Results.FeatureActionID == FeatureActions.FeatureActionID) \ - .filter(FeatureActions.SamplingFeatureID == SamplingFeatures.SamplingFeatureID) \ - .filter(FeatureActions.ActionID == Actions.ActionID) \ - .filter(Actions.MethodID == Methods.MethodID) \ - .filter(Results.ProcessingLevelID == ProcessingLevels.ProcessingLevelID) \ - .filter(Results.ResultTypeCV == resultTypeCV) \ - .order_by(Results.ResultID) - resultList = [] - if sfID: - q = q.filter(SamplingFeatures.SamplingFeatureID == sfID) - if resultID: - q = q.filter(Results.ResultID == resultID) - - for a, r, sc, sn, m, v, p, u in q.all(): - detailedResult = DetailedResult( - a, r, sc, sn, m, v, p, u - ) - resultList.append(detailedResult) - return resultList - - # Taxonomic Classifiers - def getTaxonomicClassifiers(self): - """ - getTaxonomicClassifiers(self): - * Pass nothing - return a list of all objects - - """ - return self._session.query(TaxonomicClassifiers).all() - - # Variable - def getVariables(self, ids=None, codes=None, sitecode=None, results=False): - """ - * Pass nothing - returns full list of variable objects - * Pass a list of VariableID - returns a single variable object - * Pass a list of VariableCode - returns a single variable object - * Pass a SiteCode - returns a list of Variable objects that are collected at the given site. - * Pass whether or not you want to return the sampling features that have results associated with them - - """ - if sitecode: - try: - variables = [ - x[0] for x in - self._session.query(distinct(Results.VariableID)) - .filter(Results.FeatureActionID == FeatureActions.FeatureActionID) - .filter(FeatureActions.SamplingFeatureID == SamplingFeatures.SamplingFeatureID) - .filter(SamplingFeatures.SamplingFeatureCode == sitecode).all() - ] - if ids: - ids = list(set(ids).intersection(variables)) - else: - ids = variables - except Exception as e: - print('Error running Query: {}'.format(e)) - pass - - if results: - try: - variables = [x[0] for x in self._session.query(distinct(Results.VariableID)).all()] - if ids: - ids = list(set(ids).intersection(variables)) - else: - ids = variables - except Exception as e: - print('Error running Query: {}'.format(e)) - pass - - query = self._session.query(Variables) - if ids: - query = query.filter(Variables.VariableID.in_(ids)) - if codes: - query = query.filter(Variables.VariableCode.in_(codes)) - try: - return query.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Method - def getMethods(self, ids=None, codes=None, methodtype=None, **kwargs): - """ - * Pass nothing - returns full list of method objects - * Pass a list of MethodIDs - returns a single method object for each given id - * Pass a list of MethodCode - returns a single method object for each given code - * Pass a MethodType - returns a list of method objects of the given MethodType - - """ - self._check_kwargs(['type'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the medtype parameter instead.', - DeprecationWarning, stacklevel=2) - methodtype = kwargs['type'] - - q = self._session.query(Methods) - if ids: - q = q.filter(Methods.MethodID.in_(ids)) - if codes: - q = q.filter(Methods.MethodCode.in_(codes)) - if methodtype: - q = q.filter_by(MethodTypeCV=methodtype) - - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # ProcessingLevel - def getProcessingLevels(self, ids=None, codes=None): - """ - Retrieve a list of Processing Levels - - If no arguments are passed to the function, or their values are None, - all Processing Levels objects in the database will be returned. - - Args: - ids (list, optional): List of Processing Levels IDs. - codes (list, optional): List of Processing Levels Codes. - - - Returns: - list: List of ProcessingLevels Objects - - Examples: - >>> READ = ReadODM2(SESSION_FACTORY) - >>> READ.getProcessingLevels(ids=[1, 3]) - >>> READ.getProcessingLevels(codes=['L1', 'L3']) - - """ - q = self._session.query(ProcessingLevels) - if ids: - q = q.filter(ProcessingLevels.ProcessingLevelID.in_(ids)) - if codes: - q = q.filter(ProcessingLevels.ProcessingLevelCode.in_(codes)) - - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Sampling Feature - def getSamplingFeatures(self, ids=None, codes=None, uuids=None, - sftype=None, wkt=None, results=False, **kwargs): - """Retrieve a list of Sampling Feature objects. - - If no arguments are passed to the function, or their values are None, - all Sampling Feature objects in the database will be returned. - - Args: - ids (list, optional): List of SamplingFeatureIDs. - codes (list, optional): List of SamplingFeature Codes. - uuids (list, optional): List of UUIDs string. - sftype (str, optional): Type of Sampling Feature from - `controlled vocabulary name `_. - wkt (str, optional): SamplingFeature Well Known Text. - results (bool, optional): Whether or not you want to return only the - sampling features that have results associated with them. - - Returns: - list: List of Sampling Feature objects - - Examples: - >>> READ = ReadODM2(SESSION_FACTORY) - >>> READ.getSamplingFeatures(ids=[39, 40]) - >>> READ.getSamplingFeatures(codes=['HOME', 'FIELD']) - >>> READ.getSamplingFeatures(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', - ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) - >>> READ.getSamplingFeatures(type='Site') - >>> READ.getSamplingFeatures(wkt='POINT (30 10)') - >>> READ.getSamplingFeatures(results=True) - >>> READ.getSamplingFeatures(type='Site', results=True) - - """ - self._check_kwargs(['type'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the sftype parameter instead.', - DeprecationWarning, stacklevel=2) - sftype = kwargs['type'] - if results: - try: - fas = [x[0] for x in self._session.query(distinct(Results.FeatureActionID)).all()] - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - sf = [x[0] for x in self._session.query(distinct(FeatureActions.SamplingFeatureID)).filter(FeatureActions.FeatureActionID.in_(fas)).all()] # noqa - if ids: - ids = list(set(ids).intersection(sf)) - else: - ids = sf - - q = self._session.query(SamplingFeatures) - - if sftype: - q = q.filter_by(SamplingFeatureTypeCV=sftype) - if ids: - q = q.filter(SamplingFeatures.SamplingFeatureID.in_(ids)) - if codes: - q = q.filter(SamplingFeatures.SamplingFeatureCode.in_(codes)) - if uuids: - q = q.filter(SamplingFeatures.SamplingFeatureUUID.in_(uuids)) - if wkt: - q = q.filter_by(FeatureGeometryWKT=wkt) - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - def getRelatedSamplingFeatures(self, sfid=None, rfid=None, relationshiptype=None): - # TODO: add functionality to filter by code - """ - * Pass a SamplingFeatureID - get a list of sampling feature objects - related to the input sampling feature - * Pass a RelatedFeatureID - get a list of Sampling features objects through the related feature - * Pass a RelationshipTypeCV - get a list of sampling feature objects with the given type - - """ - - sf = self._session.query(distinct(SamplingFeatures.SamplingFeatureID)) \ - .select_from(RelatedFeatures) - - if sfid: - sf = sf.join(RelatedFeatures.RelatedFeatureObj).filter(RelatedFeatures.SamplingFeatureID == sfid) - if rfid: - sf = sf.join(RelatedFeatures.SamplingFeatureObj).filter(RelatedFeatures.RelatedFeatureID == rfid) - if relationshiptype: - sf = sf.filter(RelatedFeatures.RelationshipTypeCV == relationshiptype) - try: - sfids = [x[0] for x in sf.all()] - if len(sfids) > 0: - sflist = self.getSamplingFeatures(ids=sfids) - return sflist - - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Action - def getActions(self, ids=None, acttype=None, sfid=None, **kwargs): - """ - * Pass nothing - returns a list of all Actions - * Pass a list of Action ids - returns a list of Action objects - * Pass a ActionTypeCV - returns a list of Action objects of that type - * Pass a SamplingFeature ID - returns a list of Action objects - associated with that Sampling feature ID, Found through featureAction table - - """ - self._check_kwargs(['type'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the acttype parameter instead.', - DeprecationWarning, stacklevel=2) - acttype = kwargs['type'] - a = Actions - if acttype == 'equipment': - a = EquipmentActions - elif acttype == 'calibration': - a = CalibrationActions - elif acttype == 'maintenance': - a = MaintenanceActions - - q = self._session.query(a) - if ids: - q = q.filter(a.ActionID.in_(ids)) - if sfid: - q = q.join(FeatureActions).filter(FeatureActions.SamplingFeatureID == sfid) - - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - def getRelatedActions(self, actionid=None): - """ - * Pass an ActionID - get a list of Action objects related to the input - action along with the relationship type - - """ - - q = self._session.query(Actions).select_from(RelatedActions).join(RelatedActions.RelatedActionObj) - if actionid: - q = q.filter(RelatedActions.ActionID == actionid) - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Unit - def getUnits(self, ids=None, name=None, unittype=None, **kwargs): - """ - * Pass nothing - returns a list of all units objects - * Pass a list of UnitsID - returns a single units object for the given id - * Pass UnitsName - returns a single units object - * Pass a type- returns a list of all objects of the given type - - """ - self._check_kwargs(['type'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the unittype parameter instead.', - DeprecationWarning, stacklevel=2) - unittype = kwargs['type'] - q = self._session.query(Units) - if ids: - q = q.filter(Units.UnitsID.in_(ids)) - if name: - q = q.filter(Units.UnitsName.ilike(name)) - if unittype: - q = q.filter(Units.UnitsTypeCV.ilike(unittype)) - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Organization - def getOrganizations(self, ids=None, codes=None): - """ - * Pass nothing - returns a list of all organization objects - * Pass a list of OrganizationID - returns a single organization object - * Pass a list of OrganizationCode - returns a single organization object - - """ - q = self._session.query(Organizations) - if ids: - q = q.filter(Organizations.OrganizationID.in_(ids)) - if codes: - q = q.filter(Organizations.OrganizationCode.in_(codes)) - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Person - def getPeople(self, ids=None, firstname=None, lastname=None): - """ - * Pass nothing - returns a list of all People objects - * Pass a list of PeopleID - returns a single People object - * Pass a First Name - returns a single People object - * Pass a Last Name - returns a single People object - - """ - q = self._session.query(People) - if ids: - q = q.filter(People.PersonID.in_(ids)) - if firstname: - q = q.filter(People.PersonFirstName.ilike(firstname)) - if lastname: - q = q.filter(People.PersonLastName.ilike(lastname)) - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - def getAffiliations(self, ids=None, personfirst=None, personlast=None, orgcode=None): - """Retrieve a list of Affiliation objects. - - If no arguments are passed to the function, or their values are None, - all Affiliation objects in the database will be returned. - - Args: - ids (list, optional): List of AffiliationIDs. - personfirst (str, optional): Person First Name. - personlast (str, optional): Person Last Name. - orgcode (str, optional): Organization Code. - - Returns: - list: List of Affiliation objects - - Examples: - >>> ReadODM2.getAffiliations(ids=[39,40]) - >>> ReadODM2.getAffiliations(personfirst='John', - ... personlast='Smith') - >>> ReadODM2.getAffiliations(orgcode='Acme') - - """ - q = self._session.query(Affiliations) - - if ids: - q = q.filter(Affiliations.AffiliationID.in_(ids)) - if orgcode: - q = q.join(Affiliations.OrganizationObj).filter(Organizations.OrganizationCode.ilike(orgcode)) - if personfirst: - q = q.join(Affiliations.PersonObj).filter(People.PersonFirstName.ilike(personfirst)) - if personlast: - q = q.join(Affiliations.PersonObj).filter(People.PersonLastName.ilike(personlast)) - - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Results - def getResults(self, ids=None, restype=None, uuids=None, actionid=None, simulationid=None, - variableid=None, siteid=None, sfids=None, sfuuids=None, sfcodes=None, **kwargs): - - # TODO what if user sends in both type and actionid vs just actionid - """Retrieve a list of Result objects. - - If no arguments are passed to the function, or their values are None, - all Result objects in the database will be returned. - - Args: - ids (list, optional): List of ResultIDs. - restype (str, optional): Type of Result from - `controlled vocabulary name `_. - uuids (list, optional): List of UUIDs string. - actionid (int, optional): ActionID. - simulationid (int, optional): SimulationID. - 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(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) - >>> ReadODM2.getResults(siteid=6) - >>> ReadODM2.getResults(variableid=7) - >>> ReadODM2.getResults(actionid=20) - - """ - query = self._session.query(Results) - self._check_kwargs(['type', 'sfid'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the restype parameter instead.', - DeprecationWarning, stacklevel=2) - restype = kwargs['type'] - if restype: - query = query.filter_by(ResultTypeCV=restype) - if variableid: - query = query.filter_by(VariableID=variableid) - if ids: - query = query.filter(Results.ResultID.in_(ids)) - if uuids: - query = query.filter(Results.ResultUUID.in_(uuids)) - if simulationid: - query = query.join(FeatureActions) \ - .join(Actions) \ - .join(Simulations) \ - .filter_by(SimulationID=simulationid) - if actionid: - query = query.join(FeatureActions).filter_by(ActionID=actionid) - if 'sfid' in kwargs: - warnings.warn('The parameter \'sfid\' is deprecated. ' - 'Please use the sfids parameter instead and send in a list.', - DeprecationWarning, stacklevel=2) - if kwargs['sfid']: - query = query.join(FeatureActions).filter_by(SamplingFeatureID=kwargs['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) - .join(RelatedFeatures.SamplingFeatureObj) - .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: - return query.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Datasets - def getDataSets(self, ids=None, codes=None, uuids=None, dstype=None): - """ - Retrieve a list of Datasets - - Args: - ids (list, optional): List of DataSetsIDs. - codes (list, optional): List of DataSet Codes. - uuids (list, optional): List of Dataset UUIDs string. - dstype (str, optional): Type of Dataset from - `controlled vocabulary name `_. - - - Returns: - list: List of DataSets Objects - - Examples: - >>> READ = ReadODM2(SESSION_FACTORY) - >>> READ.getDataSets(ids=[39, 40]) - >>> READ.getDataSets(codes=['HOME', 'FIELD']) - >>> READ.getDataSets(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', - ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) - >>> READ.getDataSets(dstype='singleTimeSeries') - - """ - q = self._session.query(DataSets) - if ids: - q = q.filter(DataSets.DataSetID.in_(ids)) - if codes: - q = q.filter(DataSets.DataSetCode.in_(codes)) - if uuids: - q.filter(DataSets.DataSetUUID.in_(uuids)) - if dstype: - q = q.filter(DataSets.DataSetTypeCV == dstype) - try: - return q.all() - except Exception as e: - print('Error running Query {}'.format(e)) - return None - - # Datasets - - def getDataSetsResults(self, ids=None, codes=None, uuids=None, dstype=None): - """ - Retrieve a detailed list of Datasets along with detailed metadata about the datasets - and the results contained within them - - **Must specify either DataSetID OR DataSetUUID OR DataSetCode)** - Args: - ids (list, optional): List of DataSetsIDs. - codes (list, optional): List of DataSet Codes. - uuids (list, optional): List of Dataset UUIDs string. - dstype (str, optional): Type of Dataset from - `controlled vocabulary name `_. - - - Returns: - list: List of DataSetsResults Objects - - Examples: - >>> READ = ReadODM2(SESSION_FACTORY) - >>> READ.getDataSetsResults(ids=[39, 40]) - >>> READ.getDataSetsResults(codes=['HOME', 'FIELD']) - >>> READ.getDataSetsResults(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', - ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) - >>> READ.getDataSetsResults(dstype='singleTimeSeries') - - """ - - # make sure one of the three arguments has been sent in - if all(v is None for v in [ids, codes, uuids]): - raise ValueError('Expected DataSetID OR DataSetUUID OR DataSetCode argument') - - q = self._session.query(DataSetsResults) \ - .join(DataSets) - if ids: - q = q.filter(DataSets.DataSetID.in_(ids)) - if codes: - q = q.filter(DataSets.DataSetCode.in_(codes)) - if uuids: - q.filter(DataSets.DataSetUUID.in_(uuids)) - if dstype: - q = q.filter(DataSets.DataSetTypeCV == dstype) - try: - return q.all() - except Exception as e: - print('Error running Query {}'.format(e)) - return None - - def getDataSetsValues(self, ids=None, codes=None, uuids=None, dstype=None, lowercols=True): - """ - Retrieve a list of datavalues associated with the given dataset info - - **Must specify either DataSetID OR DataSetUUID OR DataSetCode)** - Args: - ids (list, optional): List of DataSetsIDs. - codes (list, optional): List of DataSet Codes. - uuids (list, optional): List of Dataset UUIDs string. - dstype (str, optional): Type of Dataset from - `controlled vocabulary name `_. - lowercols (bool, optional): Make column names to be lowercase. - Default to True. - **Please start upgrading your code to rely on CamelCase column names, - In a near-future release, - the default will be changed to False, - and later the parameter may be removed**. - - - Returns: - list: List of Result Values Objects - - Examples: - >>> READ = ReadODM2(SESSION_FACTORY) - >>> READ.getDataSetsValues(ids=[39, 40]) - >>> READ.getDataSetsValues(codes=['HOME', 'FIELD']) - >>> READ.getDataSetsValues(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', - ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) - >>> READ.getDataSetsValues(dstype='singleTimeSeries', lowercols=False) - - """ - - dsr = self.getDataSetsResults(ids, codes, uuids, dstype) - - resids = [] - for ds in dsr: - resids.append(ds.ResultID) - - try: - return self.getResultValues(resultids=resids, lowercols=lowercols) - except Exception as e: - print('Error running Query {}'.format(e)) - return None - - def getSamplingFeatureDatasets(self, ids=None, codes=None, uuids=None, dstype=None, sftype=None): - """ - Retrieve a list of Datasets associated with the given sampling feature data. - - **Must specify either samplingFeatureID OR samplingFeatureUUID OR samplingFeatureCode)** - - Args: - ids (list, optional): List of SamplingFeatureIDs. - codes (list, optional): List of SamplingFeature Codes. - uuids (list, optional): List of UUIDs string. - dstype (str, optional): Type of Dataset from - `controlled vocabulary name `_. - sftype (str, optional): Type of SamplingFeature from - `controlled vocabulary name `_. - - Returns: - list: List of DataSetsResults Objects associated with the given sampling feature - - Examples: - >>> READ = ReadODM2(SESSION_FACTORY) - >>> READ.getSamplingFeatureDatasets(ids=[39, 40]) - >>> READ.getSamplingFeatureDatasets(codes=['HOME', 'FIELD']) - >>> READ.getSamplingFeatureDatasets(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', - ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) - >>> READ.getSamplingFeatureDatasets(dstype='singleTimeSeries') - >>> READ.getSamplingFeatureDatasets(sftype='Specimen') - - """ - - # make sure one of the three arguments has been sent in - if all(v is None for v in [ids, codes, uuids, sftype]): - raise ValueError( - 'Expected samplingFeatureID OR samplingFeatureUUID ' - 'OR samplingFeatureCode OR samplingFeatureType ' - 'argument') - - sf_query = self._session.query(SamplingFeatures) - if sftype: - sf_query = sf_query.filter(SamplingFeatures.SamplingFeatureTypeCV == sftype) - if ids: - sf_query = sf_query.filter(SamplingFeatures.SamplingFeatureID.in_(ids)) - if codes: - sf_query = sf_query.filter(SamplingFeatures.SamplingFeatureCode.in_(codes)) - if uuids: - sf_query = sf_query.filter(SamplingFeatures.SamplingFeatureUUID.in_(uuids)) - - sf_list = [] - for sf in sf_query.all(): - sf_list.append(sf) - - try: - sfds = [] - for sf in sf_list: - - q = self._session.query(DataSetsResults) \ - .join(Results) \ - .join(FeatureActions) \ - .filter(FeatureActions.SamplingFeatureID == sf.SamplingFeatureID) - - if dstype: - q = q.filter_by(DatasetTypeCV=dstype) - - vals = q.all() - - related = self.getRelatedSamplingFeatures(sf.SamplingFeatureID) - - sfds.append(SamplingFeatureDataSet(sf, vals, related)) - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - return sfds - - # Data Quality - def getDataQuality(self): - """ - * Pass nothing - return a list of all objects - """ - return self._session.query(DataQuality).all() - - # TODO DataQuality Schema Queries - def getReferenceMaterials(self): - """ - * Pass nothing - return a list of all objects - """ - return self._session.query(ReferenceMaterials).all() - - def getReferenceMaterialValues(self): - """ - * Pass nothing - return a list of all objects - """ - return self._session.query(ReferenceMaterialValues).all() - - def getResultNormalizationValues(self): - """ - * Pass nothing - return a list of all objects - """ - return self._session.query(ResultNormalizationValues).all() - - def getResultsDataQuality(self): - """ - * Pass nothing - return a list of all objects - """ - return self._session.query(ResultsDataQuality).all() - - # TODO Equipment Schema Queries - # Equipment - def getEquipment(self, codes=None, equiptype=None, sfid=None, actionid=None, **kwargs): - """ - * Pass nothing - returns a list of all Equipment objects - * Pass a list of EquipmentCodes- return a list of all Equipment objects that match each of the codes - * Pass a EquipmentType - returns a single Equipment object - * Pass a SamplingFeatureID - returns a single Equipment object - * Pass an ActionID - returns a single Equipment object - - """ - self._check_kwargs(['type'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the equiptype parameter instead.', - DeprecationWarning, stacklevel=2) - equiptype = kwargs['type'] - - # NOTE: Equiptype currently unused! - if equiptype: - pass - e = self._session.query(Equipment) - if sfid: - e = e.join(EquipmentUsed) \ - .join(Actions) \ - .join(FeatureActions) \ - .filter(FeatureActions.SamplingFeatureID == sfid) - if codes: - e = e.filter(Equipment.EquipmentCode.in_(codes)) - if actionid: - e = e.join(EquipmentUsed).join(Actions) \ - .filter(Actions.ActionID == actionid) - return e.all() - - def CalibrationReferenceEquipment(self): - """ - * Pass nothing - return a list of all objects - - """ - return self._session.query(CalibrationReferenceEquipment).all() - - def CalibrationStandards(self): - """ - * Pass nothing - return a list of all objects - - """ - return self._session.query(CalibrationStandards).all() - - def DataloggerFileColumns(self): - """ - * Pass nothing - return a list of all objects - - """ - return self._session.query(DataLoggerFileColumns).all() - - def DataLoggerFiles(self): - """ - * Pass nothing - return a list of all objects - - """ - return self._session.query(DataLoggerFiles).all() - - def DataloggerProgramFiles(self): - """ - * Pass Nothing - return a list of all objects - - """ - return self._session.query(DataLoggerProgramFiles).all() - - def EquipmentModels(self): - """ - * Pass Nothing - return a list of all objects - - """ - return self._session.query(EquipmentModels).all() - - def EquipmentUsed(self): - """ - * Pass Nothing - return a list of all objects - - """ - return self._session.query(EquipmentUsed).all() - - def InstrumentOutputVariables(self, modelid=None, variableid=None): - """ - * Pass Nothing - return a list of all objects - * Pass ModelID - * Pass VariableID - - """ - i = self._session.query(InstrumentOutputVariables) - if modelid: - i = i.filter_by(ModelID=modelid) - if variableid: - i = i.filter_by(VariableID=variableid) - return i.all() - - def RelatedEquipment(self, code=None): - """ - * Pass nothing - return a list of all objects - * Pass code- return a single object with the given code - - """ - r = self._session.query(RelatedEquipment) - if code: - r = r.filter_by(EquipmentCode=code) - return r.all() - - # Extension Properties - def getExtensionProperties(self, exptype=None, **kwargs): - """ - * Pass nothing - return a list of all objects - * Pass type- return a list of all objects of the given type - - """ - # Todo what values to use for extensionproperties type - self._check_kwargs(['type'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the exptype parameter instead.', - DeprecationWarning, stacklevel=2) - exptype = kwargs['type'] - e = ExtensionProperties - if exptype == 'action': - e = ActionExtensionPropertyValues - elif exptype == 'citation': - e = CitationExtensionPropertyValues - elif exptype == 'method': - e = MethodExtensionPropertyValues - elif exptype == 'result': - e = ResultExtensionPropertyValues - elif exptype == 'samplingfeature': - e = SamplingFeatureExtensionPropertyValues - elif exptype == 'variable': - e = VariableExtensionPropertyValues - try: - return self._session.query(e).all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # External Identifiers - def getExternalIdentifiers(self, eitype=None, **kwargs): - """ - * Pass nothing - return a list of all objects - * Pass type- return a list of all objects of the given type - - """ - self._check_kwargs(['type'], kwargs) - if 'type' in kwargs: - warnings.warn('The parameter \'type\' is deprecated. Please use the eitype parameter instead.', - DeprecationWarning, stacklevel=2) - eitype = kwargs['type'] - e = ExternalIdentifierSystems - if eitype.lowercase == 'citation': - e = CitationExternalIdentifiers - elif eitype == 'method': - e = MethodExternalIdentifiers - elif eitype == 'person': - e = PersonExternalIdentifiers - elif eitype == 'referencematerial': - e = ReferenceMaterialExternalIdentifiers - elif eitype == 'samplingfeature': - e = SamplingFeatureExternalIdentifiers - elif eitype == 'spatialreference': - e = SpatialReferenceExternalIdentifiers - elif eitype == 'taxonomicclassifier': - e = TaxonomicClassifierExternalIdentifiers - elif eitype == 'variable': - e = VariableExternalIdentifiers - try: - return self._session.query(e).all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # TODO functions for Lab Analyses - # Lab Analyses - def getDirectives(self): - """ - getDirectives(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(Directives).all() - - def getActionDirectives(self): - """ - getActionDirectives(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(ActionDirectives).all() - - def getSpecimenBatchPositions(self): - """ - getSpecimenBatchPositions(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(SpecimenBatchPositions).all() - - # TODO functions for Provenance - # Provenance - def getAuthorLists(self): - """ - getAuthorLists(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(AuthorLists).all() - - def getDatasetCitations(self): - """ - getDatasetCitations(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(DataSetCitations).all() - - def getDerivationEquations(self): - """ - getDerivationEquations(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(DerivationEquations).all() - - def getMethodCitations(self): - """ - getMethodCitations(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(MethodCitations).all() - - def getRelatedAnnotations(self): - """ - getRelatedAnnotations(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(RelatedAnnotations).all() - - def getRelatedCitations(self): - """ - getRelatedCitations(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(RelatedCitations).all() - - def getRelatedDatasets(self): - """ - getRelatedDatasets(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(RelatedDataSets).all() - - def getRelatedResults(self): - """ - getRelatedResults(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(RelatedResults).all() - - def getResultDerivationEquations(self): - """ - getResultDerivationEquations(self) - * Pass nothing - return a list of all objects - - """ - return self._session.query(ResultDerivationEquations).all() - - def getResultValues(self, resultids, starttime=None, endtime=None, lowercols=True): - """ - Retrieve result values associated with the given result. - - **The resultids must be associated with the same result type** - Args: - resultids (list): List of SamplingFeatureIDs. - starttime (object, optional): Start time to filter by as datetime object. - endtime (object, optional): End time to filter by as datetime object. - lowercols (bool, optional): Make column names to be lowercase. - Default to True. - **Please start upgrading your code to rely on CamelCase column names, - In a near-future release, - the default will be changed to False, - and later the parameter may be removed**. - - Returns: - DataFrame: Pandas dataframe of result values. - - Examples: - >>> READ = ReadODM2(SESSION_FACTORY) - >>> READ.getResultValues(resultids=[10, 11]) - >>> READ.getResultValues(resultids=[100, 20, 34], starttime=datetime.today()) - >>> READ.getResultValues(resultids=[1, 2, 3, 4], - >>> starttime=datetime(2000, 01, 01), - >>> endtime=datetime(2003, 02, 01), lowercols=False) - - """ - restype = self._session.query(Results).filter_by(ResultID=resultids[0]).first().ResultTypeCV - ResultValues = TimeSeriesResultValues - if 'categorical' in restype.lower(): - ResultValues = CategoricalResultValues - elif 'measurement' in restype.lower(): - ResultValues = MeasurementResultValues - elif 'point' in restype.lower(): - ResultValues = PointCoverageResultValues - elif 'profile' in restype.lower(): - ResultValues = ProfileResultValues - elif 'section' in restype.lower(): - ResultValues = SectionResults - elif 'spectra' in restype.lower(): - ResultValues = SpectraResultValues - elif 'time' in restype.lower(): - ResultValues = TimeSeriesResultValues - elif 'trajectory' in restype.lower(): - ResultValues = TrajectoryResultValues - elif 'transect' in restype.lower(): - ResultValues = TransectResultValues - - q = self._session.query(ResultValues).filter(ResultValues.ResultID.in_(resultids)) - if starttime: - q = q.filter(ResultValues.ValueDateTime >= starttime) - if endtime: - q = q.filter(ResultValues.ValueDateTime <= endtime) - try: - # F841 local variable 'vals' is assigned to but never used - # vals = q.order_by(ResultType.ValueDateTime) - query = q.statement.compile(dialect=self._session_factory.engine.dialect) - df = pd.read_sql_query( - sql=query, - con=self._session_factory.engine, - params=query.params - ) - if not lowercols: - df.columns = [self._get_columns(ResultValues)[c] for c in df.columns] - else: - warnings.warn( - 'In a near-future release, ' - 'the parameter \'lowercols\' default will be changed to False, ' - 'and later the parameter may be removed.', - DeprecationWarning, stacklevel=2) - return df - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # SamplingFeatures - # Site - def getSpatialReferences(self, srsCodes=None): - """ - getSpatialReferences(self, srsCodes=None) - * Pass nothing - return a list of all Spatial References - * Pass in a list of SRS Codes- - - """ - q = self._session.query(SpatialReferences) - if srsCodes: - q.filter(SpatialReferences.SRSCode.in_(srsCodes)) - try: - return q.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - # Simulation - def getSimulations(self, name=None, actionid=None): - """ - getSimulations(self, name=None, actionid=None) - * Pass nothing - get a list of all converter simuation objects - * Pass a SimulationName - get a single simulation object - * Pass an ActionID - get a single simulation object - - """ - s = self._session.query(Simulations) - if name: - s = s.filter(Simulations.SimulationName.ilike(name)) - if actionid: - s = s.filter_by(ActionID=actionid) - try: - return s.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - def getModels(self, codes=None): - """ - getModels(self, codes=None) - * Pass nothing - return a list of all Model Objects - * Pass a list of ModelCodes - get a list of converter objects related to the converter having ModeCode - - """ - m = self._session.query(Models) - if codes: - m = m.filter(Models.ModelCode.in_(codes)) - try: - return m.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None - - def getRelatedModels(self, modid=None, code=None, **kwargs): - """ - getRelatedModels(self, id=None, code=None) - * Pass a ModelID - get a list of converter objects related to the converter having ModelID - * Pass a ModelCode - get a list of converter objects related to the converter having ModeCode - - """ - self._check_kwargs(['id'], kwargs) - if 'id' in kwargs: - warnings.warn('The parameter \'id\' is deprecated. Please use the modid parameter instead.', - DeprecationWarning, stacklevel=2) - modid = kwargs['id'] - m = self._session.query(Models).select_from(RelatedModels).join(RelatedModels.ModelObj) - if modid: - m = m.filter(RelatedModels.ModelID == modid) - if code: - m = m.filter(Models.ModelCode == code) - - try: - return m.all() - except Exception as e: - print('Error running Query: {}'.format(e)) - return None +def ReadODM2(*args, **kwargs): + warnings.warn('The class odm2api.ODM2.services.readService.ReadODM2 will be deprecated. ' + 'Please use odm2api.services.readService.ReadODM2 instead.', + FutureWarning, stacklevel=2) + return newClass(*args, **kwargs) diff --git a/odm2api/ODM2/services/updateService.py b/odm2api/ODM2/services/updateService.py index 87e77b8..6b70c82 100644 --- a/odm2api/ODM2/services/updateService.py +++ b/odm2api/ODM2/services/updateService.py @@ -1,93 +1,18 @@ from __future__ import (absolute_import, division, print_function) -__author__ = 'jmeline' - -from datetime import datetime - -from odm2api.ODM2 import serviceBase -from odm2api.ODM2.models import (Actions, Results) - - -# ################################################################################ -# Annotations -# ################################################################################ +import warnings -class UpdateODM2(serviceBase): - def update(self, value): - self._session.add(value) - self._session.commit() - return value +from odm2api.services import UpdateODM2 as newClass - # ################################################################################ - # Core - # ################################################################################ - def updateResultValidDateTime(self, resultId, dateTime): +warnings.warn('The module odm2api.ODM2.services.updateService will be deprecated. ' + 'Please use odm2api.services.updateService instead.', + FutureWarning, stacklevel=2) - # check type of "validdatetime' - # if not datetime do this: - # dt = dateTime.to_datetime() - # else dt = dateTime - if (type(dateTime) != datetime): - dt = dateTime.to_datetime() - else: - dt = dateTime - q = self._session.query(Results).filter(Results.ResultID == int(resultId)) - q.update({'ValidDateTime': dt}) - - self._session.commit() - - def updateResult(self, resultID=None, valuecount=None, result=None): - if resultID: - q = self._session.query(Results).filter(Results.ResultID == int(resultID)) - if valuecount: - q.update({'ValueCount': valuecount}) - if result: - self._session.add(result) - self._session.commit() - - def updateAction(self, actionID=None, begin=None, end=None, action=None): - if actionID: - q = self._session.query(Actions).filter(Actions.ActionID == int(actionID)) - # if (type(begin) != datetime): - # begin = begin.to_datetime() - # if (type(end) != datetime): - # end = end.to_datetime() +__author__ = 'jmeline' - if begin: - q.update({'BeginDateTime': begin}) - if end: - q.update({'EndDateTime': end}) - elif action: - self._session.add(action) - self._session.commit() -# ################################################################################ -# Data Quality -# ################################################################################ -# ################################################################################ -# Equipment -# ################################################################################ -# ################################################################################ -# Extension Properties -# ################################################################################ -# ################################################################################ -# External Identifiers -# ################################################################################ -# ################################################################################ -# Lab Analyses -# ################################################################################ -# ################################################################################ -# Provenance -# ################################################################################ -# ################################################################################ -# Results -# ################################################################################ -# ################################################################################ -# Sampling Features -# ################################################################################ -# ################################################################################ -# Sensors -# ################################################################################ -################################################################################ -# ODM2 -# ################################################################################ +def UpdateODM2(*args, **kwargs): + warnings.warn('The class odm2api.ODM2.services.readService.CreateODM2 will be deprecated. ' + 'Please use odm2api.services.readService.CreateODM2 instead.', + FutureWarning, stacklevel=2) + return newClass(*args, **kwargs) diff --git a/odm2api/ODMconnection.py b/odm2api/ODMconnection.py index c3c1833..1a10b74 100644 --- a/odm2api/ODMconnection.py +++ b/odm2api/ODMconnection.py @@ -7,7 +7,7 @@ except ImportError: from urllib.parse import quote_plus -from odm2api.ODM2.models import setSchema +from odm2api.models import setSchema from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker diff --git a/odm2api/__init__.py b/odm2api/__init__.py index 830dc2e..fbb8991 100644 --- a/odm2api/__init__.py +++ b/odm2api/__init__.py @@ -1,11 +1,12 @@ from __future__ import (absolute_import, division, print_function) from odm2api.ODMconnection import SessionFactory, dbconnection -from odm2api.base import serviceBase +from odm2api.base import modelBase, serviceBase __all__ = [ 'SessionFactory', 'dbconnection', + 'modelBase', 'serviceBase', ] diff --git a/odm2api/models.py b/odm2api/models.py new file mode 100644 index 0000000..5f8c4ac --- /dev/null +++ b/odm2api/models.py @@ -0,0 +1,1929 @@ +from __future__ import (absolute_import, division, print_function) + +from odm2api.base import modelBase + +from sqlalchemy import BigInteger, Boolean, Column, Date, DateTime, Float, ForeignKey, Integer, String, case +from sqlalchemy.dialects import mysql, postgresql, sqlite +from sqlalchemy.orm import relationship + +Base = modelBase.Base + +BigIntegerType = BigInteger() +BigIntegerType = BigIntegerType.with_variant(sqlite.INTEGER(), 'sqlite') +BigIntegerType = BigIntegerType.with_variant(postgresql.BIGINT(), 'postgresql') +BigIntegerType = BigIntegerType.with_variant(mysql.BIGINT(), 'mysql') + +DateTimeType = DateTime() +DateTimeType = DateTimeType.with_variant(sqlite.INTEGER(), 'sqlite') + + +def is_hex(s): + try: + int(s, base=16) + return True + except ValueError: + return False + + +################################################################################ +# CV +################################################################################ +class CV(object): + __table_args__ = {u'schema': 'odm2'} + + Term = Column('term', String(255), nullable=False) + Name = Column('name', String(255), primary_key=True) + Definition = Column('definition', String(1000)) + Category = Column('category', String(255)) + SourceVocabularyURI = Column('sourcevocabularyuri', String(255)) + + +class CVActionType(Base, CV): + __tablename__ = 'cv_actiontype' + + +class CVAggregationStatistic(Base, CV): + __tablename__ = 'cv_aggregationstatistic' + + +class CVAnnotationType(Base, CV): + __tablename__ = 'cv_annotationtype' + + +class CVCensorCode(Base, CV): + __tablename__ = 'cv_censorcode' + + +class CVDataQualityType(Base, CV): + __tablename__ = 'cv_dataqualitytype' + + +class CVDataSetType(Base, CV): + __tablename__ = 'cv_datasettypecv' + + +class CVDeploymentType(Base, CV): + __tablename__ = 'cv_deploymenttype' + + +class CVDirectiveType(Base, CV): + __tablename__ = 'cv_directivetype' + + +class CVElevationDatum(Base, CV): + __tablename__ = 'cv_elevationdatum' + + +class CVEquipmentType(Base, CV): + __tablename__ = 'cv_equipmenttype' + + +class CVMediumType(Base, CV): + __tablename__ = 'cv_medium' + + +class CVMethodType(Base, CV): + __tablename__ = 'cv_methodtype' + + +class CVOrganizationType(Base, CV): + __tablename__ = 'cv_organizationtype' + + +class CVPropertyDataType(Base, CV): + __tablename__ = 'cv_propertydatatype' + + +class CVQualityCode(Base, CV): + __tablename__ = 'cv_qualitycode' + + +class CVResultType(Base, CV): + __tablename__ = 'cv_resulttype' + + +class CVRelationshipType(Base, CV): + __tablename__ = 'cv_relationshiptype' + + +class CVSamplingFeatureGeoType(Base, CV): + __tablename__ = 'cv_samplingfeaturegeotype' + + +class CVSamplingFeatureType(Base, CV): + __tablename__ = 'cv_samplingfeaturetype' + + +class CVSpatialOffsetType(Base, CV): + __tablename__ = 'cv_spatialoffsettype' + + +class CVSpeciation(Base, CV): + __tablename__ = 'cv_speciation' + + +class CVSpecimenType(Base, CV): + __tablename__ = 'cv_specimentype' + + +class CVSiteType(Base, CV): + __tablename__ = 'cv_sitetype' + + +class CVStatus(Base, CV): + __tablename__ = 'cv_status' + + +class CVTaxonomicClassifierType(Base, CV): + __tablename__ = 'cv_taxonomicclassifiertype' + + +class CVUnitsType(Base, CV): + __tablename__ = 'cv_unitstype' + + +class CVVariableName(Base, CV): + __tablename__ = 'cv_variablename' + + +class CVVariableType(Base, CV): + __tablename__ = 'cv_variabletype' + + +class CVReferenceMaterialMedium(Base, CV): + __tablename__ = 'cv_referencematerialmedium' + + +# ################################################################################ +# Core +# ################################################################################ +class People(Base): + """ + Individuals that perform actions. + """ + PersonID = Column('personid', Integer, primary_key=True, nullable=False) + PersonFirstName = Column('personfirstname', String(255), nullable=False) + PersonMiddleName = Column('personmiddlename', String(255)) + PersonLastName = Column('personlastname', String(255), nullable=False) + + +class Organizations(Base): + """ + A group of people. + """ + OrganizationID = Column('organizationid', Integer, primary_key=True, nullable=False) + OrganizationTypeCV = Column('organizationtypecv', ForeignKey(CVOrganizationType.Name), nullable=False, + index=True) + OrganizationCode = Column('organizationcode', String(50), nullable=False) + OrganizationName = Column('organizationname', String(255), nullable=False) + OrganizationDescription = Column('organizationdescription', String(500)) + OrganizationLink = Column('organizationlink', String(255)) + ParentOrganizationID = Column('parentorganizationid', ForeignKey('odm2.organizations.organizationid')) + + OrganizationObj = relationship(u'Organizations', remote_side=[OrganizationID]) + + +class Affiliations(Base): + AffiliationID = Column('affiliationid', Integer, primary_key=True, nullable=False) + PersonID = Column('personid', ForeignKey(People.PersonID), nullable=False) + OrganizationID = Column('organizationid', ForeignKey(Organizations.OrganizationID)) + IsPrimaryOrganizationContact = Column('isprimaryorganizationcontact', Boolean) + AffiliationStartDate = Column('affiliationstartdate', Date, nullable=False) + AffiliationEndDate = Column('affiliationenddate', Date) + PrimaryPhone = Column('primaryphone', String(50)) + PrimaryEmail = Column('primaryemail', String(255), nullable=False) + PrimaryAddress = Column('primaryaddress', String(255)) + PersonLink = Column('personlink', String(255)) + + OrganizationObj = relationship(Organizations) + PersonObj = relationship(People) + + +class Methods(Base): + """ + The procedure used to perform an action. + """ + MethodID = Column('methodid', Integer, primary_key=True, nullable=False) + MethodTypeCV = Column('methodtypecv', ForeignKey(CVMethodType.Name), nullable=False, index=True) + MethodCode = Column('methodcode', String(50), nullable=False) + MethodName = Column('methodname', String(255), nullable=False) + MethodDescription = Column('methoddescription', String(500)) + MethodLink = Column('methodlink', String(255)) + OrganizationID = Column('organizationid', Integer, ForeignKey(Organizations.OrganizationID)) + + OrganizationObj = relationship(Organizations) + + +class Actions(Base): + """ + Actions are performed by people and may have a result. + """ + ActionID = Column('actionid', Integer, primary_key=True, nullable=False) + ActionTypeCV = Column('actiontypecv', ForeignKey(CVActionType.Name), nullable=False, index=True) + MethodID = Column('methodid', ForeignKey(Methods.MethodID), nullable=False) + BeginDateTime = Column('begindatetime', DateTime, nullable=False) + BeginDateTimeUTCOffset = Column('begindatetimeutcoffset', Integer, nullable=False) + EndDateTime = Column('enddatetime', DateTime) + EndDateTimeUTCOffset = Column('enddatetimeutcoffset', Integer) + ActionDescription = Column('actiondescription', String(500)) + ActionFileLink = Column('actionfilelink', String(255)) + + MethodObj = relationship(Methods) + + +class ActionBy(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ActionID = Column('actionid', Integer, ForeignKey(Actions.ActionID), nullable=False) + AffiliationID = Column('affiliationid', ForeignKey(Affiliations.AffiliationID), nullable=False) + IsActionLead = Column('isactionlead', Boolean, nullable=False) + RoleDescription = Column('roledescription', String(500)) + + ActionObj = relationship(Actions) + AffiliationObj = relationship(Affiliations) + + +class SamplingFeatures(Base): + """ + Where or on what an action was performed. + """ + SamplingFeatureID = Column('samplingfeatureid', Integer, primary_key=True, nullable=False) + """int: Primary key identifier.""" + SamplingFeatureUUID = Column('samplingfeatureuuid', String(36), nullable=False) + """str: A universally unique identifier for the sampling feature.""" + SamplingFeatureTypeCV = Column('samplingfeaturetypecv', ForeignKey(CVSamplingFeatureType.Name), + nullable=False, index=True) + """str: CV term describing the type of sampling feature.""" + SamplingFeatureCode = Column('samplingfeaturecode', String(50), nullable=False) + """str: A short but meaningful text identifier for the sampling feature.""" + SamplingFeatureName = Column('samplingfeaturename', String(255)) + """str: Sampling Feature name (free text).""" + SamplingFeatureDescription = Column('samplingfeaturedescription', String(500)) + """str: Text describing the sampling feature.""" + SamplingFeatureGeotypeCV = Column('samplingfeaturegeotypecv', ForeignKey(CVSamplingFeatureGeoType.Name), + index=True) + """str: Dimensionality of SamplingFeature; point2d, line2d, etc.""" + Elevation_m = Column('elevation_m', Float(53)) + """float: The elevation of the sampling feature in meters, or in the case of Specimen, + the elevation from where the SamplingFeature.Specimen was collected""" # noqa + ElevationDatumCV = Column('elevationdatumcv', ForeignKey(CVElevationDatum.Name), index=True) + """str: The code for the vertical geodetic datum that specifies the zero point for + the Sampling Feature Elevation""" # noqa + # FeatureGeometry = Column('featuregeometry', String(50)) + """object: The location geometry of the sampling feature on the Earth expressed using a + geometry data type. Can be a Point, Curve (profile, trajectory, etc), + Surface (flat polygons, etc) or Solid/Volume (although often limited to + 2D geometries). """ # noqa + + FeatureGeometryWKT = Column('featuregeometrywkt', String(50)) + """str: The location geometry of the sampling feature on the Earth expressed as + well known text (WKT). Can be a Point, Curve (profile, trajectory, etc.), + Surface (flat polygons, etc.), or Solid/Volume (although often limited to + 2D geometries).""" # noqa + __mapper_args__ = { + 'polymorphic_on': case( + [ + (SamplingFeatureTypeCV == 'Specimen', 'Specimen'), + (SamplingFeatureTypeCV == 'Site', 'Site'), + ], + else_='samplingfeatures'), + 'polymorphic_identity': 'samplingfeatures', + } + + +class FeatureActions(Base): + """ + Provides flexible linkage between Actions and the SamplingFeatures + on which or at which they were performed. + """ + FeatureActionID = Column('featureactionid', Integer, primary_key=True, nullable=False) + SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), + nullable=False) + ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) + + ActionObj = relationship(Actions) + SamplingFeatureObj = relationship(SamplingFeatures) + + +class DataSets(Base): + """ + Enables grouping of results into a larger dataset. + """ + DataSetID = Column('datasetid', Integer, primary_key=True, nullable=False) + + # This has been changed to String to support multiple database uuid types + DataSetUUID = Column('datasetuuid', String(255), nullable=False) + DataSetTypeCV = Column('datasettypecv', ForeignKey(CVDataSetType.Name), nullable=False, index=True) + DataSetCode = Column('datasetcode', String(50), nullable=False) + DataSetTitle = Column('datasettitle', String(255), nullable=False) + DataSetAbstract = Column('datasetabstract', String(500), nullable=False) + + +class ProcessingLevels(Base): + """ + Levels to which data have been quality controlled. + """ + ProcessingLevelID = Column('processinglevelid', Integer, primary_key=True, nullable=False) + ProcessingLevelCode = Column('processinglevelcode', String(50), nullable=False) + Definition = Column('definition', String(500)) + Explanation = Column('explanation', String(500)) + + +class RelatedActions(Base): + """ + Enables specifying relationships among Actions (e.g., workflows, etc.) + """ + RelationID = Column('relationid', Integer, primary_key=True, nullable=False) + ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) + RelationshipTypeCV = Column('relationshiptypecv', ForeignKey(CVRelationshipType.Name), nullable=False, + index=True) + RelatedActionID = Column('relatedactionid', ForeignKey(Actions.ActionID), nullable=False) + + ActionObj = relationship(Actions, primaryjoin='RelatedActions.ActionID == Actions.ActionID') + RelatedActionObj = relationship(Actions, primaryjoin='RelatedActions.RelatedActionID == Actions.ActionID') + + +class TaxonomicClassifiers(Base): + """ + Terms for classifying results. + """ + TaxonomicClassifierID = Column('taxonomicclassifierid', Integer, primary_key=True, nullable=False) + TaxonomicClassifierTypeCV = Column( + 'taxonomicclassifiertypecv', + ForeignKey(CVTaxonomicClassifierType.Name), + nullable=False, + index=True + ) + TaxonomicClassifierName = Column('taxonomicclassifiername', String(255), + nullable=False) + TaxonomicClassifierCommonName = Column('taxonomicclassifiercommonname', String(255)) + TaxonomicClassifierDescription = Column('taxonomicclassifierdescription', String(500)) + ParentTaxonomicClassifierID = Column('parenttaxonomicclassifierid', + ForeignKey('odm2.taxonomicclassifiers.taxonomicclassifierid')) + + parent = relationship(u'TaxonomicClassifiers', remote_side=[TaxonomicClassifierID]) + + +class Units(Base): + """ + Units of measure. + """ + UnitsID = Column('unitsid', Integer, primary_key=True, nullable=False) + UnitsTypeCV = Column('unitstypecv', ForeignKey(CVUnitsType.Name), nullable=False, index=True) + UnitsAbbreviation = Column('unitsabbreviation', String(255), nullable=False) + UnitsName = Column('unitsname', String, nullable=False) + UnitsLink = Column('unitslink', String(255)) + + +class Variables(Base): + """ + What was observed. + """ + VariableID = Column('variableid', Integer, primary_key=True, nullable=False) + VariableTypeCV = Column('variabletypecv', ForeignKey(CVVariableType.Name), nullable=False, index=True) + VariableCode = Column('variablecode', String(50), nullable=False) + VariableNameCV = Column('variablenamecv', ForeignKey(CVVariableName.Name), nullable=False, index=True) + VariableDefinition = Column('variabledefinition', String(500)) + SpeciationCV = Column('speciationcv', ForeignKey(CVSpeciation.Name), index=True) + NoDataValue = Column('nodatavalue', Float(asdecimal=True), nullable=False) + + +class Results(Base): + """ + The result of an action. + """ + ResultID = Column('resultid', BigIntegerType, primary_key=True) + + # This has been changed to String to support multiple database uuid types + # ResultUUID = Column(UNIQUEIDENTIFIER, nullable=False) + ResultUUID = Column('resultuuid', String(36), nullable=False) + FeatureActionID = Column('featureactionid', ForeignKey(FeatureActions.FeatureActionID), nullable=False) + ResultTypeCV = Column('resulttypecv', ForeignKey(CVResultType.Name), nullable=False, index=True) + VariableID = Column('variableid', ForeignKey(Variables.VariableID), nullable=False) + UnitsID = Column('unitsid', ForeignKey(Units.UnitsID), nullable=False) + TaxonomicClassifierID = Column('taxonomicclassifierid', + ForeignKey(TaxonomicClassifiers.TaxonomicClassifierID)) + ProcessingLevelID = Column('processinglevelid', ForeignKey(ProcessingLevels.ProcessingLevelID), + nullable=False) + ResultDateTime = Column('resultdatetime', DateTime) + ResultDateTimeUTCOffset = Column('resultdatetimeutcoffset', BigIntegerType) + ValidDateTime = Column('validdatetime', DateTime) + ValidDateTimeUTCOffset = Column('validdatetimeutcoffset', BigIntegerType) + StatusCV = Column('statuscv', ForeignKey(CVStatus.Name), index=True) + SampledMediumCV = Column('sampledmediumcv', ForeignKey(CVMediumType.Name), nullable=False, index=True) + ValueCount = Column('valuecount', Integer, nullable=False) + + FeatureActionObj = relationship(FeatureActions) + ProcessingLevelObj = relationship(ProcessingLevels) + + TaxonomicClassifierObj = relationship(TaxonomicClassifiers) + UnitsObj = relationship(Units) + VariableObj = relationship(Variables) + + __mapper_args__ = { + 'polymorphic_on': case([ + (ResultTypeCV == 'Point coverage', 'Point coverage'), + (ResultTypeCV == 'Profile Coverage', 'Profile Coverage'), + (ResultTypeCV == 'Category coverage', 'Category coverage'), + (ResultTypeCV == 'Transect Coverage', 'Transect Coverage'), + (ResultTypeCV == 'Spectra coverage', 'Spectra coverage'), + (ResultTypeCV == 'Time series coverage', 'Time series coverage'), + (ResultTypeCV == 'Section coverage', 'Section coverage'), + (ResultTypeCV == 'Profile Coverage', 'Profile Coverage'), + (ResultTypeCV == 'Trajectory coverage', 'Trajectory coverage'), + (ResultTypeCV == 'Measurement', 'Measurement'), + ], else_='results'), + 'polymorphic_identity': 'results', + } + + +# ################################################################################ +# Equipment +# ################################################################################ + + +class DataLoggerProgramFiles(Base): + ProgramID = Column('programid', Integer, primary_key=True, nullable=False) + AffiliationID = Column('affiliationid', Integer, ForeignKey(Affiliations.AffiliationID), nullable=False) + ProgramName = Column('programname', String(255), nullable=False) + ProgramDescription = Column('programdescription', String(500)) + ProgramVersion = Column('programversion', String(50)) + ProgramFileLink = Column('programfilelink', String(255)) + + AffiliationObj = relationship(Affiliations) + + +class DataLoggerFiles(Base): + DataLoggerFileID = Column('dataloggerfileid', Integer, primary_key=True, nullable=False) + ProgramID = Column('programid', Integer, ForeignKey(DataLoggerProgramFiles.ProgramID), nullable=False) + DataLoggerFileName = Column('dataloggerfilename', String(255), nullable=False) + DataLoggerOutputFileDescription = Column('dataloggerfiledescription', String(500)) + DataLoggerOutputFileLink = Column('dataloggerfilelink', String(255)) + + ProgramObj = relationship(DataLoggerProgramFiles) + + +class EquipmentModels(Base): + ModelID = Column('modelid', Integer, primary_key=True, nullable=False) + ModelManufacturerID = Column('modelmanufacturerid', Integer, + ForeignKey(Organizations.OrganizationID), nullable=False) + ModelPartNumber = Column('modelpartnumber', String(50)) + ModelName = Column('modelname', String(255), nullable=False) + ModelDescription = Column('modeldescription', String(500)) + ModelSpecificationsFileLink = Column('modelspecificationsfilelink', String(255)) + ModelLink = Column('modellink', String(255)) + IsInstrument = Column('isinstrument', Boolean, nullable=False) + + OrganizationObj = relationship(Organizations) + + +class InstrumentOutputVariables(Base): + InstrumentOutputVariableID = Column( + 'instrumentoutputvariableid', + Integer, + primary_key=True, + nullable=False + ) + ModelID = Column('modelid', Integer, ForeignKey(EquipmentModels.ModelID), nullable=False) + VariableID = Column('variableid', Integer, ForeignKey(Variables.VariableID), nullable=False) + InstrumentMethodID = Column('instrumentmethodid', Integer, ForeignKey(Methods.MethodID), nullable=False) + InstrumentResolution = Column('instrumentresolution', String(255)) + InstrumentAccuracy = Column('instrumentaccuracy', String(255)) + InstrumentRawOutputUnitsID = Column('instrumentrawoutputunitsid', Integer, ForeignKey(Units.UnitsID), + nullable=False) + + MethodObj = relationship(Methods) + OutputUnitObj = relationship(Units) + EquipmentModelObj = relationship(EquipmentModels) + VariableObj = relationship(Variables) + + +class DataLoggerFileColumns(Base): + DataLoggerFileColumnID = Column('dataloggerfilecolumnid', Integer, primary_key=True, nullable=False) + ResultID = Column('resultid', BigIntegerType, ForeignKey(Results.ResultID)) + DataLoggerFileID = Column('dataloggerfileid', Integer, + ForeignKey(DataLoggerFiles.DataLoggerFileID), nullable=False) + InstrumentOutputVariableID = Column('instrumentoutputvariableid', Integer, + ForeignKey(InstrumentOutputVariables.VariableID), + nullable=False) + ColumnLabel = Column('columnlabel', String(50), nullable=False) + ColumnDescription = Column('columndescription', String(500)) + MeasurementEquation = Column('measurementequation', String(255)) + ScanInterval = Column('scaninterval', Float(50)) + ScanIntervalUnitsID = Column('scanintervalunitsid', Integer, ForeignKey(Units.UnitsID)) + RecordingInterval = Column('recordinginterval', Float(50)) + RecordingIntervalUnitsID = Column('recordingintervalunitsid', Integer, ForeignKey(Units.UnitsID)) + AggregationStatisticCV = Column( + 'aggregationstatisticcv', + String(255), + ForeignKey(CVAggregationStatistic.Name), + index=True + ) + + ResultObj = relationship(Results) + DataLoggerFileObj = relationship(DataLoggerFiles) + InstrumentOutputVariableObj = relationship(InstrumentOutputVariables) + ScanIntervalUnitsObj = relationship( + Units, + primaryjoin='DataLoggerFileColumns.ScanIntervalUnitsID == Units.UnitsID' + ) + RecordingIntervalUnitsObj = relationship( + Units, + primaryjoin='DataLoggerFileColumns.RecordingIntervalUnitsID == Units.UnitsID' + ) + + +class Equipment(Base): + EquipmentID = Column('equipmentid', Integer, primary_key=True, nullable=False) + EquipmentCode = Column('equipmentcode', String(50), nullable=False) + EquipmentName = Column('equipmentname', String(255), nullable=False) + EquipmentTypeCV = Column('equipmenttypecv', ForeignKey(CVEquipmentType.Name), nullable=False, index=True) + ModelID = Column('modelid', ForeignKey(EquipmentModels.ModelID), nullable=False) + EquipmentSerialNumber = Column('equipmentseriealnumber', String(50), nullable=False) + EquipmentInventoryNumber = Column('equipmentinventorynumber', String(50)) + EquipmentOwnerID = Column('equipmentownerid', ForeignKey(People.PersonID), nullable=False) + EquipmentVendorID = Column('equipmentvendorid', ForeignKey(Organizations.OrganizationID), nullable=False) + EquipmentPurchaseDate = Column('equipmentpurchasedate', DateTime, nullable=False) + EquipmentPurchaseOrderNumber = Column('equipmentpurchaseordernumber', String(50)) + EquipmentDescription = Column('equipmentdescription', String(500)) + + PersonObj = relationship(People) + OrganizationObj = relationship(Organizations) + EquipmentModelObj = relationship(EquipmentModels) + + +class CalibrationReferenceEquipment(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ActionID = Column('actionid', Integer, ForeignKey(Actions.ActionID), nullable=False) + EquipmentID = Column('equipmentid', Integer, ForeignKey(Equipment.EquipmentID), nullable=False) + + ActionObj = relationship(Actions) + EquipmentObj = relationship(Equipment) + + +class EquipmentActions(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + EquipmentID = Column('equipmentid', ForeignKey(Equipment.EquipmentID), nullable=False) + ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) + + ActionObj = relationship(Actions) + EquipmentObj = relationship(Equipment) + + +class EquipmentUsed(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ActionID = Column('actionid', Integer, ForeignKey(Actions.ActionID), nullable=False) + EquipmentID = Column('equipmentid', Integer, ForeignKey(Equipment.EquipmentID), nullable=False) + + ActionObj = relationship(Actions) + EquipmentObj = relationship(Equipment) + + +class MaintenanceActions(Base): + ActionID = Column('actionid', Integer, ForeignKey(Actions.ActionID), primary_key=True, nullable=False) + IsFactoryService = Column('isfactoryservce', Boolean, nullable=False) + MaintenanceCode = Column('maintenancecode', String(50)) + MantenanceReason = Column('maintenancereason', String(50)) + + ActionObj = relationship(Actions) + + +class RelatedEquipment(Base): + RelationID = Column('relationid', Integer, primary_key=True, nullable=True) + EquipmentID = Column('equipmentid', Integer, ForeignKey(Equipment.EquipmentID), nullable=True) + RelationshipTypeCV = Column('relationshiptypecv', String(255), nullable=True, index=True) + RelatedEquipmentID = Column( + 'relatedequipmentid', + Integer, + ForeignKey(Equipment.EquipmentID), + nullable=True + ) + RelationshipStartDateTime = Column('relationshipstartdatetime', DateTime, nullable=True) + RelationshipStartDateTimeUTCOffset = Column('relationshipstartdatetimeutcoffset', Integer, nullable=True) + RelationshipEndDateTime = Column('relationshipenddatetime', DateTime) + RelationshipEndDateTimeUTCOffset = Column('relationshipenddatetimeutcoffset', Integer) + + EquipmentObj = relationship( + Equipment, + primaryjoin='RelatedEquipment.EquipmentID == Equipment.EquipmentID' + ) + RelatedEquipmentObj = relationship( + Equipment, + primaryjoin='RelatedEquipment.RelatedEquipmentID == Equipment.EquipmentID' + ) + + +class CalibrationActions(Base): + ActionID = Column('actionid', Integer, ForeignKey(Actions.ActionID), primary_key=True, nullable=False) + CalibrationCheckValue = Column('calibrationcheckvalue', Float(53)) + InstrumentOutputVariableID = Column('instrumentoutputvariableid', Integer, + ForeignKey(InstrumentOutputVariables.VariableID), nullable=False) + CalibrationEquation = Column('calibrationequation', String(255)) + + ActionObj = relationship(Actions) + InstrumentOutputVariableObj = relationship(InstrumentOutputVariables) + + +# ################################################################################ +# Lab Analyses +# ################################################################################ + + +class Directives(Base): + DirectiveID = Column('directiveid', Integer, primary_key=True, nullable=False) + DirectiveTypeCV = Column('directivetypecv', ForeignKey(CVDirectiveType.Name), nullable=False, index=True) + DirectiveDescription = Column('directivedescription', String(500), nullable=False) + + +class ActionDirectives(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) + DirectiveID = Column('directiveid', ForeignKey(Directives.DirectiveID), nullable=False) + + ActionObj = relationship(Actions) + DirectiveObj = relationship(Directives) + + +class SpecimenBatchPositions(Base): + # todo fix misspelling + __tablename__ = u'specimenbatchpostions' + + FeatureActionID = Column( + 'featureactionid', + Integer, + ForeignKey(FeatureActions.FeatureActionID), + primary_key=True, + nullable=False + ) + BatchPositionsNumber = Column('batchpositionnumber', Integer, nullable=False) + BatchPositionLabel = Column('batchpositionlabel', String(255)) + + FeatureActionObj = relationship(FeatureActions) + + +# ################################################################################ +# Sampling Features +# ################################################################################ +class SpatialReferences(Base): + SpatialReferenceID = Column('spatialreferenceid', Integer, primary_key=True, nullable=False) + SRSCode = Column('srscode', String(50)) + SRSName = Column('srsname', String(255), nullable=False) + SRSDescription = Column('srsdescription', String(500)) + SRSLink = Column('srslink', String(255)) + + +class Specimens(SamplingFeatures): + SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), + primary_key=True) + SpecimenTypeCV = Column('specimentypecv', ForeignKey(CVSpecimenType.Name), nullable=False, index=True) + SpecimenMediumCV = Column('specimenmediumcv', ForeignKey(CVMediumType.Name), nullable=False, index=True) + IsFieldSpecimen = Column('isfieldspecimen', Boolean, nullable=False) + + __mapper_args__ = { + 'polymorphic_identity': 'Specimen', + } + + +class SpatialOffsets(Base): + SpatialOffsetID = Column('spatialoffsetid', Integer, primary_key=True, nullable=False) + SpatialOffsetTypeCV = Column('spatialoffsettypecv', ForeignKey(CVSpatialOffsetType.Name), nullable=False, + index=True) + Offset1Value = Column('offset1value', Float(53), nullable=False) + Offset1UnitID = Column('offset1unitid', Integer, ForeignKey(Units.UnitsID), nullable=False) + Offset2Value = Column('offset2value', Float(53)) + Offset2UnitID = Column('offset2unitid', Integer, ForeignKey(Units.UnitsID)) + Offset3Value = Column('offset3value', Float(53)) + Offset3UnitID = Column('offset3unitid', Integer, ForeignKey(Units.UnitsID)) + + Offset1UnitObj = relationship(Units, primaryjoin='SpatialOffsets.Offset1UnitID == Units.UnitsID') + Offset2UnitObj = relationship(Units, primaryjoin='SpatialOffsets.Offset2UnitID == Units.UnitsID') + Offset3UnitObj = relationship(Units, primaryjoin='SpatialOffsets.Offset3UnitID == Units.UnitsID') + + +class Sites(SamplingFeatures): + SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), + primary_key=True) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID), + nullable=False) + SiteTypeCV = Column('sitetypecv', ForeignKey(CVSiteType.Name), nullable=False, index=True) + Latitude = Column('latitude', Float(53), nullable=False) + Longitude = Column('longitude', Float(53), nullable=False) + + SpatialReferenceObj = relationship(SpatialReferences) + + __mapper_args__ = { + 'polymorphic_identity': 'Site', + } + + +class RelatedFeatures(Base): + RelationID = Column('relationid', Integer, primary_key=True, nullable=False) + SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), + nullable=False) + RelationshipTypeCV = Column('relationshiptypecv', ForeignKey(CVRelationshipType.Name), nullable=False, + index=True) + RelatedFeatureID = Column( + 'relatedfeatureid', + ForeignKey(SamplingFeatures.SamplingFeatureID), + nullable=False + ) + SpatialOffsetID = Column('spatialoffsetid', ForeignKey(SpatialOffsets.SpatialOffsetID)) + + SamplingFeatureObj = relationship( + SamplingFeatures, + primaryjoin='RelatedFeatures.SamplingFeatureID == SamplingFeatures.SamplingFeatureID' + ) + RelatedFeatureObj = relationship( + SamplingFeatures, + primaryjoin='RelatedFeatures.RelatedFeatureID == SamplingFeatures.SamplingFeatureID' + ) + SpatialOffsetObj = relationship(SpatialOffsets) + + +class SpecimenTaxonomicClassifiers(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + SamplingFeatureID = Column('samplingfeatureid', ForeignKey(Specimens.SamplingFeatureID), nullable=False) + TaxonomicClassifierID = Column('taxonomicclassifierid', + ForeignKey(TaxonomicClassifiers.TaxonomicClassifierID), nullable=False) + CitationID = Column('citationid', Integer) + + SpecimenObj = relationship(Specimens) + TaxonomicClassifierObj = relationship(TaxonomicClassifiers) + + +# ################################################################################ +# Simulation +# ################################################################################ +class Models(Base): + ModelID = Column('modelid', Integer, primary_key=True, nullable=False) + ModelCode = Column('modelcode', String(255), nullable=False) + ModelName = Column('modelname', String(255), nullable=False) + ModelDescription = Column('modeldescription', String(500)) + + +class RelatedModels(Base): + RelatedID = Column('relatedid', Integer, primary_key=True, nullable=False) + ModelID = Column('modelid', ForeignKey(Models.ModelID), nullable=False) + RelationshipTypeCV = Column('relationshiptypecv', ForeignKey(CVRelationshipType.Name), nullable=False, + index=True) + RelatedModelID = Column('relatedmodelid', ForeignKey(Models.ModelID), nullable=False) + + ModelObj = relationship(Models, primaryjoin='RelatedModels.ModelID == Models.ModelID') + RelatedModelObj = relationship(Models, primaryjoin='RelatedModels.RelatedModelID == Models.ModelID') + + +class Simulations(Base): + SimulationID = Column('simulationid', Integer, primary_key=True, nullable=False) + ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) + SimulationName = Column('simulationname', String(255), nullable=False) + SimulationDescription = Column('simulationdescription', String(500)) + SimulationStartDateTime = Column('simulationstartdatetime', Date, nullable=False) + SimulationStartDateTimeUTCOffset = Column('simulationstartdatetimeutcoffset', Integer, nullable=False) + SimulationEndDateTime = Column('simulationenddatetime', Date, nullable=False) + SimulationEndDateTimeUTCOffset = Column('simulationenddatetimeutcoffset', Integer, nullable=False) + TimeStepValue = Column('timestepvalue', Float(53), nullable=False) + TimeStepUnitsID = Column('timestepunitsid', ForeignKey(Units.UnitsID), nullable=False) + InputDataSetID = Column('inputdatasetid', ForeignKey(DataSets.DataSetID)) + # OutputDataSetID = Column('outputdatasetid', Integer) # What's this ? + ModelID = Column('modelid', ForeignKey(Models.ModelID), nullable=False) + + Action = relationship(Actions) + DataSet = relationship(DataSets) + Model = relationship(Models) + Unit = relationship(Units) + + +# Part of the Provenance table, needed here to meet dependencies +class Citations(Base): + CitationID = Column('citationid', Integer, primary_key=True, nullable=False) + Title = Column('title', String(255), nullable=False) + Publisher = Column('publisher', String(255), nullable=False) + PublicationYear = Column('publicationyear', Integer, nullable=False) + CitationLink = Column('citationlink', String(255)) + + +# ################################################################################ +# Annotations +# ################################################################################ +class Annotations(Base): + AnnotationID = Column('annotationid', Integer, primary_key=True, nullable=False) + AnnotationTypeCV = Column( + 'annotationtypecv', + ForeignKey(CVAnnotationType.Name), + nullable=False, + index=True + ) + AnnotationCode = Column('annotationcode', String(50)) + AnnotationText = Column('annotationtext', String(500), nullable=False) + AnnotationDateTime = Column('annotationdatetime', DateTime) + AnnotationUTCOffset = Column('annotationutcoffset', Integer) + AnnotationLink = Column('annotationlink', String(255)) + AnnotatorID = Column('annotatorid', ForeignKey(People.PersonID)) + CitationID = Column('citationid', ForeignKey(Citations.CitationID)) + + # PersonObj = relationship(People) + AnnotatorObj = relationship(People) + CitationObj = relationship(Citations) + + +class ActionAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + ActionObj = relationship(Actions) + AnnotationObj = relationship(Annotations) + + +class EquipmentAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + EquipmentID = Column('valueid', BigIntegerType, ForeignKey(Equipment.EquipmentID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + EquipmentObj = relationship(Equipment) + + +class MethodAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + MethodID = Column('methodid', ForeignKey(Methods.MethodID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + MethodObj = relationship(Methods) + + +class ResultAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ResultID = Column('resultid', ForeignKey(Results.ResultID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + BeginDateTime = Column('begindatetime', DateTime, nullable=False) + EndDateTime = Column('enddatetime', DateTime, nullable=False) + + AnnotationObj = relationship(Annotations) + ResultObj = relationship(Results) + + +class SamplingFeatureAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), + nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + SamplingFeatureObj = relationship(SamplingFeatures) + + +# ################################################################################ +# Data Quality +# ################################################################################ +class DataSetsResults(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + DataSetID = Column('datasetid', ForeignKey(DataSets.DataSetID), nullable=False) + ResultID = Column('resultid', ForeignKey(Results.ResultID), nullable=False) + + DataSetObj = relationship(DataSets) + ResultObj = relationship(Results) + + +class DataQuality(Base): + DataQualityID = Column('dataqualityid', Integer, primary_key=True, nullable=False) + DataQualityTypeCV = Column('dataqualitytypecv', ForeignKey(CVDataQualityType.Name), nullable=False, + index=True) + DataQualityCode = Column('dataqualitycode', String(255), nullable=False) + DataQualityValue = Column('dataqualityvalue', Float(53)) + DataQualityValueUnitsID = Column('dataqualityvalueunitsid', ForeignKey(Units.UnitsID)) + DataQualityDescription = Column('dataqualitydescription', String(500)) + DataQualityLink = Column('dataqualitylink', String(255)) + + UnitObj = relationship(Units) + + +class ReferenceMaterials(Base): + ReferenceMaterialID = Column('referencematerialid', Integer, primary_key=True, nullable=False) + ReferenceMaterialMediumCV = Column( + 'referencematerialmediumcv', + ForeignKey(CVReferenceMaterialMedium.Name), + nullable=False, + index=True + ) + ReferenceMaterialOrganizationID = Column('referencematerialoranizationid', + ForeignKey(Organizations.OrganizationID), nullable=False) + ReferenceMaterialCode = Column('referencematerialcode', String(50), nullable=False) + ReferenceMaterialLotCode = Column('referencemateriallotcode', String(255)) + ReferenceMaterialPurchaseDate = Column('referencematerialpurchasedate', DateTime) + ReferenceMaterialExpirationDate = Column('referencematerialexpirationdate', DateTime) + ReferenceMaterialCertificateLink = Column('referencematerialcertificatelink', String(255)) + SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID)) + + OrganizationObj = relationship(Organizations) + SamplingFeatureObj = relationship(SamplingFeatures) + + +class CalibrationStandards(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ActionID = Column('actionid', Integer, ForeignKey(Actions.ActionID), nullable=False) + ReferenceMaterialID = Column( + 'referencematerialid', + Integer, + ForeignKey(ReferenceMaterials.ReferenceMaterialID), + nullable=False + ) + + ActionObj = relationship(Actions) + ReferenceMaterialObj = relationship(ReferenceMaterials) + + +class ReferenceMaterialValues(Base): + ReferenceMaterialValueID = Column('referencematerialvalueid', Integer, primary_key=True, nullable=False) + ReferenceMaterialID = Column('referencematerialid', ForeignKey(ReferenceMaterials.ReferenceMaterialID), + nullable=False) + ReferenceMaterialValue = Column('referencematerialvalue', Float(53), nullable=False) + ReferenceMaterialAccuracy = Column('referencematerialaccuracy', Float(53)) + VariableID = Column('variableid', ForeignKey(Variables.VariableID), nullable=False) + UnitsID = Column('unitsid', ForeignKey(Units.UnitsID), nullable=False) + CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) + + CitationObj = relationship(Citations) + ReferenceMaterialObj = relationship(ReferenceMaterials) + UnitObj = relationship(Units) + VariableObj = relationship(Variables) + + +class ResultNormalizationValues(Base): + ResultID = Column(u'resultid', ForeignKey(Results.ResultID), primary_key=True) + ReferenceMaterialValueID = Column(u'referencematerialvalueid', + ForeignKey(ReferenceMaterialValues.ReferenceMaterialValueID), + nullable=False) + + ResultsObj = relationship(Results) + ReferenceMaterialValueObj = relationship(ReferenceMaterialValues) + + +class ResultsDataQuality(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ResultID = Column('resultid', ForeignKey(Results.ResultID), nullable=False) + DataQualityID = Column('dataqualityid', ForeignKey(DataQuality.DataQualityID), nullable=False) + + DataQualityObj = relationship(DataQuality) + ResultObj = relationship(Results) + + +# ################################################################################ +# Extension Properties +# ################################################################################ +class ExtensionProperties(Base): + PropertyID = Column('propertyid', Integer, primary_key=True, nullable=False) + PropertyName = Column('propertyname', String(255), nullable=False) + PropertyDescription = Column('propertydescription', String(500)) + PropertyDataTypeCV = Column('propertydatatypecv', ForeignKey(CVPropertyDataType.Name), nullable=False, + index=True) + PropertyUnitsID = Column('propertyunitsid', ForeignKey(Units.UnitsID)) + + UnitObj = relationship(Units) + + +class ActionExtensionPropertyValues(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) + PropertyID = Column('propertyid', ForeignKey(ExtensionProperties.PropertyID), nullable=False) + PropertyValue = Column('propertyvalue', String(255), nullable=False) + + ActionObj = relationship(Actions) + ExtensionPropertyObj = relationship(ExtensionProperties) + + +class CitationExtensionPropertyValues(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) + PropertyID = Column('propertyid', ForeignKey(ExtensionProperties.PropertyID), nullable=False) + PropertyValue = Column('propertyvalue', String(255), nullable=False) + + CitationObj = relationship(Citations) + ExtensionPropertyObj = relationship(ExtensionProperties) + + +class MethodExtensionPropertyValues(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + MethodID = Column('methodid', ForeignKey(Methods.MethodID), nullable=False) + PropertyID = Column('propertyid', ForeignKey(ExtensionProperties.PropertyID), nullable=False) + PropertyValue = Column('propertyvalue', String(255), nullable=False) + + MethodObj = relationship(Methods) + ExtensionPropertyObj = relationship(ExtensionProperties) + + +class ResultExtensionPropertyValues(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ResultID = Column('resultid', ForeignKey(Results.ResultID), nullable=False) + PropertyID = Column('propertyid', ForeignKey(ExtensionProperties.PropertyID), nullable=False) + PropertyValue = Column('propertyvalue', String(255), nullable=False) + + ExtensionPropertyObj = relationship(ExtensionProperties) + ResultObj = relationship(Results) + + +class SamplingFeatureExtensionPropertyValues(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), + nullable=False) + PropertyID = Column('propertyid', ForeignKey(ExtensionProperties.PropertyID), nullable=False) + PropertyValue = Column('propertyvalue', String(255), nullable=False) + + ExtensionPropertyObj = relationship(ExtensionProperties) + SamplingFeatureObj = relationship(SamplingFeatures) + + +class VariableExtensionPropertyValues(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + VariableID = Column('variableid', ForeignKey(Variables.VariableID), nullable=False) + PropertyID = Column('propertyid', ForeignKey(ExtensionProperties.PropertyID), nullable=False) + PropertyValue = Column('propertyvalue', String(255), nullable=False) + + ExtensionPropertyObj = relationship(ExtensionProperties) + VariableObj = relationship(Variables) + + +# ################################################################################ +# Extension Identifiers +# ################################################################################ +class ExternalIdentifierSystems(Base): + ExternalIdentifierSystemID = Column( + 'externalidentifiersystemid', + Integer, + primary_key=True, + nullable=False + ) + ExternalIdentifierSystemName = Column('externalidentifiersystemname', String(255), nullable=False) + IdentifierSystemOrganizationID = Column('identifiersystemorganizationid', + ForeignKey(Organizations.OrganizationID), nullable=False) + ExternalIdentifierSystemDescription = Column('externalidentifiersystemdescription', String(500)) + ExternalIdentifierSystemURL = Column('externalidentifiersystemurl', String(255)) + + IdentifierSystemOrganizationObj = relationship(Organizations) + + +class CitationExternalIdentifiers(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) + ExternalIdentifierSystemID = Column('externalidentifiersystemid', + ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), + nullable=False) + CitationExternalIdentifier = Column('citationexternaldentifier', String(255), nullable=False) + CitationExternalIdentifierURI = Column('citationexternaldentifieruri', String(255)) + + CitationObj = relationship(Citations) + ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) + + +class MethodExternalIdentifiers(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + MethodID = Column('methodid', ForeignKey(Methods.MethodID), nullable=False) + ExternalIdentifierSystemID = Column('externalidentifiersystemid', + ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), + nullable=False) + + MethodExternalIdentifier = Column('methodexternalidentifier', String(255), nullable=False) + MethodExternalIdentifierURI = Column('methodexternalidentifieruri', String(255)) + + ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) + MethodObj = relationship(Methods) + + +class PersonExternalIdentifiers(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + PersonID = Column('personid', ForeignKey(People.PersonID), nullable=False) + ExternalIdentifierSystemID = Column('externalidentifiersystemid', + ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), + nullable=False) + PersonExternalIdentifier = Column('personexternalidentifier', String(255), nullable=False) + PersonExternalIdentifierURI = Column('personexternalidentifieruri', String(255)) + + ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) + PersonObj = relationship(People) + + +class ReferenceMaterialExternalIdentifiers(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ReferenceMaterialID = Column(ForeignKey(ReferenceMaterials.ReferenceMaterialID), nullable=False) + ExternalIdentifierSystemID = Column('externalidentifiersystemid', + ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), + nullable=False) + ReferenceMaterialExternalIdentifier = Column( + 'referencematerialexternalidentifier', + String(255), + nullable=False + ) + ReferenceMaterialExternalIdentifierURI = Column('referencematerialexternalidentifieruri', String(255)) + + ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) + ReferenceMaterialObj = relationship(ReferenceMaterials) + + +class SamplingFeatureExternalIdentifiers(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), + nullable=False) + ExternalIdentifierSystemID = Column('externalidentifiersystemid', + ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), + nullable=False) + SamplingFeatureExternalIdentifier = Column( + 'samplingfeatureexternalidentifier', + String(255), + nullable=False + ) + SamplingFeatureExternalIdentifierURI = Column('samplingfeatureexternalidentifieruri', String(255)) + + ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) + SamplingFeatureObj = relationship(SamplingFeatures) + + +class SpatialReferenceExternalIdentifiers(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID), + nullable=False) + ExternalIdentifierSystemID = Column('externalidentifiersystemid', + ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), + nullable=False) + SpatialReferenceExternalIdentifier = Column( + 'spatialreferenceexternalidentifier', + String(255), + nullable=False + ) + SpatialReferenceExternalIdentifierURI = Column('spatialreferenceexternalidentifieruri', String(255)) + + ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) + SpatialReferenceObj = relationship(SpatialReferences) + + +class TaxonomicClassifierExternalIdentifiers(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + TaxonomicClassifierID = Column('taxonomicclassifierid', + ForeignKey(TaxonomicClassifiers.TaxonomicClassifierID), nullable=False) + ExternalIdentifierSystemID = Column('externalidentifiersystemid', + ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), + nullable=False) + TaxonomicClassifierExternalIdentifier = Column( + 'taxonomicclassifierexternalidentifier', + String(255), + nullable=False + ) + TaxonomicClassifierExternalIdentifierURI = Column('taxonomicclassifierexternalidentifieruri', String(255)) + + ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) + TaxonomicClassifierObj = relationship(TaxonomicClassifiers) + + +class VariableExternalIdentifiers(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + VariableID = Column('variableid', ForeignKey(Variables.VariableID), nullable=False) + ExternalIdentifierSystemID = Column('externalidentifiersystemid', + ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), + nullable=False) + VariableExternalIdentifier = Column('variableexternalidentifer', String(255), nullable=False) + VariableExternalIdentifierURI = Column('variableexternalidentifieruri', String(255)) + + ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) + VariableObj = relationship(Variables) + + +# ################################################################################ +# Provenance +# ################################################################################ + +class AuthorLists(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) + PersonID = Column('personid', ForeignKey(People.PersonID), nullable=False) + AuthorOrder = Column('authororder', Integer, nullable=False) + + CitationObj = relationship(Citations, primaryjoin='AuthorLists.CitationID == Citations.CitationID') + PersonObj = relationship(People, primaryjoin='AuthorLists.PersonID == People.PersonID') + + +class DataSetCitations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + DataSetID = Column('datasetid', ForeignKey(DataSets.DataSetID), nullable=False) + RelationshipTypeCV = Column('relationshiptypecv', ForeignKey(CVRelationshipType.Name), nullable=False, + index=True) + CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) + + CitationObj = relationship(Citations) + DataSetObj = relationship(DataSets) + + +class DerivationEquations(Base): + DerivationEquationID = Column('derivationequationid', Integer, primary_key=True, nullable=False) + DerivationEquation = Column('derivationequation', String(255), nullable=False) + + +class ResultDerivationEquations(Base): + ResultID = Column(u'resultid', ForeignKey(Results.ResultID), primary_key=True) + DerivationEquationID = Column( + u'derivationequationid', + ForeignKey(DerivationEquations.DerivationEquationID), + nullable=False + ) + + ResultsObj = relationship(Results) + DerivationEquationsObj = relationship(DerivationEquations) + + +class MethodCitations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + MethodID = Column('methodid', ForeignKey(Methods.MethodID), nullable=False) + RelationshipTypeCV = Column('relationshiptypecv', ForeignKey(CVRelationshipType.Name), nullable=False, + index=True) + CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) + + CitationObj = relationship(Citations) + MethodObj = relationship(Methods) + + +class RelatedAnnotations(Base): + RelationID = Column('relationid', Integer, primary_key=True, nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + RelationshipTypeCV = Column('relationshiptypecv', ForeignKey(CVRelationshipType.Name), nullable=False, + index=True) + RelatedAnnotationID = Column('relatedannotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship( + Annotations, + primaryjoin='RelatedAnnotations.AnnotationID == Annotations.AnnotationID' + ) + RelatedAnnotationObj = relationship( + Annotations, + primaryjoin='RelatedAnnotations.RelatedAnnotationID == Annotations.AnnotationID' + ) + + +class RelatedCitations(Base): + RelationID = Column('relationid', Integer, primary_key=True, nullable=False) + CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) + RelationshipTypeCV = Column('relationshiptypecv', ForeignKey(CVRelationshipType.Name), nullable=False, + index=True) + RelatedCitationID = Column('relatedcitationid', ForeignKey(Citations.CitationID), nullable=False) + + CitationObj = relationship(Citations, primaryjoin='RelatedCitations.CitationID == Citations.CitationID') + RelatedCitationObj = relationship( + Citations, + primaryjoin='RelatedCitations.RelatedCitationID == Citations.CitationID' + ) + + +class RelatedDataSets(Base): + RelationID = Column('relationid', Integer, primary_key=True, nullable=False) + DataSetID = Column('datasetid', ForeignKey(DataSets.DataSetID), nullable=False) + RelationshipTypeCV = Column('relationshiptypecv', ForeignKey(CVRelationshipType.Name), nullable=False, + index=True) + RelatedDataSetID = Column('relateddatasetid', ForeignKey(DataSets.DataSetID), nullable=False) + VersionCode = Column('versioncode', String(50)) + + DataSetObj = relationship(DataSets, primaryjoin='RelatedDataSets.DataSetID == DataSets.DataSetID') + RelatedDataSetObj = relationship( + DataSets, + primaryjoin='RelatedDataSets.RelatedDataSetID == DataSets.DataSetID' + ) + + +class RelatedResults(Base): + RelationID = Column('relationid', Integer, primary_key=True, nullable=False) + ResultID = Column('resultid', ForeignKey(Results.ResultID), nullable=False) + RelationshipTypeCV = Column('relationshiptypecv', ForeignKey(CVRelationshipType.Name), nullable=False, + index=True) + RelatedResultID = Column('relatedresultid', ForeignKey(Results.ResultID), nullable=False) + VersionCode = Column('versioncode', String(50)) + RelatedResultSequenceNumber = Column('relatedresultsequencenumber', Integer) + + ResultObj = relationship(Results, primaryjoin='RelatedResults.RelatedResultID == Results.ResultID') + RelatedResultObj = relationship(Results, primaryjoin='RelatedResults.ResultID == Results.ResultID') + + +# ################################################################################ +# Results +# ################################################################################ +class PointCoverageResults(Results): + ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) + ZLocation = Column('zlocation', Float(53)) + ZLocationUnitsID = Column('zlocationunitsid', ForeignKey(Units.UnitsID)) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) + IntendedXSpacing = Column('intendedxspacing', Float(53)) + IntendedXSpacingUnitsID = Column('intendedxspacingunitsid', ForeignKey(Units.UnitsID)) + IntendedYSpacing = Column('intendedyspacing', Float(53)) + IntendedYSpacingUnitsID = Column('intendedyspacingunitsid', ForeignKey(Units.UnitsID)) + AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), + nullable=False, index=True) + TimeAggregationInterval = Column('timeaggregationinterval', Float(53), nullable=False) + TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', Integer, nullable=False) + + IntendedXSpacingUnitsObj = relationship( + Units, + primaryjoin='PointCoverageResults.IntendedXSpacingUnitsID == Units.UnitsID' + ) + IntendedYSpacingUnitsObj = relationship( + Units, + primaryjoin='PointCoverageResults.IntendedYSpacingUnitsID == Units.UnitsID' + ) + SpatialReferenceObj = relationship(SpatialReferences) + ZLocationUnitsObj = relationship( + Units, + primaryjoin='PointCoverageResults.ZLocationUnitsID == Units.UnitsID' + ) + + __mapper_args__ = {'polymorphic_identity': 'Point coverage'} + + +class ProfileResults(Results): + ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) + XLocation = Column('xlocation', Float(53)) + XLocationUnitsID = Column('xlocationunitsid', ForeignKey(Units.UnitsID)) + YLocation = Column('ylocation', Float(53)) + YLocationUnitsID = Column('ylocationunitsid', ForeignKey(Units.UnitsID)) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) + IntendedZSpacing = Column('intendedzspacing', Float(53)) + IntendedZSpacingUnitsID = Column('intendedzspacingunitsid', ForeignKey(Units.UnitsID)) + IntendedTimeSpacing = Column('intendedtimespacing', Float(53)) + IntendedTimeSpacingUnitsID = Column('intendedtimespacingunitsid', ForeignKey(Units.UnitsID)) + AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), + nullable=False, index=True) + + IntendedTimeSpacingUnitsObj = relationship( + Units, + primaryjoin='ProfileResults.IntendedTimeSpacingUnitsID == Units.UnitsID' + ) + IntendedZSpacingUnitsObj = relationship( + Units, + primaryjoin='ProfileResults.IntendedZSpacingUnitsID == Units.UnitsID' + ) + SpatialReferenceObj = relationship(SpatialReferences) + XLocationUnitsObj = relationship(Units, primaryjoin='ProfileResults.XLocationUnitsID == Units.UnitsID') + YLocationUnitsObj = relationship(Units, primaryjoin='ProfileResults.YLocationUnitsID == Units.UnitsID') + + __mapper_args__ = {'polymorphic_identity': 'Profile Coverage'} + + +class CategoricalResults(Results): + ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) + XLocation = Column('xlocation', Float(53)) + XLocationUnitsID = Column('xlocationunitsid', Integer, ForeignKey(Units.UnitsID)) + YLocation = Column('ylocation', Float(53)) + YLocationUnitsID = Column('ylocationunitsid', Integer, ForeignKey(Units.UnitsID)) + ZLocation = Column('zlocation', Float(53)) + ZLocationUnitsID = Column('zlocationunitsid', Integer, ForeignKey(Units.UnitsID)) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) + QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) + + SpatialReferenceObj = relationship(SpatialReferences) + XLocationUnitsObj = relationship( + Units, + primaryjoin='CategoricalResults.XLocationUnitsID == Units.UnitsID' + ) + YLocationUnitsObj = relationship( + Units, + primaryjoin='CategoricalResults.YLocationUnitsID == Units.UnitsID' + ) + ZLocationUnitsObj = relationship( + Units, + primaryjoin='CategoricalResults.ZLocationUnitsID == Units.UnitsID' + ) + + __mapper_args__ = {'polymorphic_identity': ' Category coverage'} + + +class TransectResults(Results): + ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) + ZLocation = Column('zlocation', Float(53)) + ZLocationUnitsID = Column('zlocationunitsid', ForeignKey(Units.UnitsID)) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) + IntendedTransectSpacing = Column('intendedtransectspacing', Float(53)) + IntendedTransectSpacingUnitsID = Column('intendedtransectspacingunitsid', ForeignKey(Units.UnitsID)) + IntendedTimeSpacing = Column('intendedtimespacing', Float(53)) + IntendedTimeSpacingUnitsID = Column('intendedtimespacingunitsid', ForeignKey(Units.UnitsID)) + AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), + nullable=False, index=True) + + IntendedTimeSpacingUnitsObj = relationship( + Units, + primaryjoin='TransectResults.IntendedTimeSpacingUnitsID == Units.UnitsID' + ) + IntendedTransectSpacingUnitsObj = relationship( + Units, + primaryjoin='TransectResults.IntendedTransectSpacingUnitsID == Units.UnitsID' + ) + SpatialReferenceObj = relationship(SpatialReferences) + ZLocationUnitsObj = relationship(Units, primaryjoin='TransectResults.ZLocationUnitsID == Units.UnitsID') + + __mapper_args__ = {'polymorphic_identity': 'Transect Coverage'} + + +class SpectraResults(Results): + ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) + XLocation = Column('xlocation', Float(53)) + XLocationUnitsID = Column('xlocationunitsid', ForeignKey(Units.UnitsID)) + YLocation = Column('ylocation', Float(53)) + YLocationUnitsID = Column('ylocationunitsid', ForeignKey(Units.UnitsID)) + ZLocation = Column('zlocation', Float(53)) + ZLocationUnitsID = Column('zlocationunitsid', ForeignKey(Units.UnitsID)) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) + IntendedWavelengthSpacing = Column('intendedwavelengthspacing', Float(53)) + IntendedWavelengthSpacingUnitsID = Column('intendedwavelengthspacingunitsid', ForeignKey(Units.UnitsID)) + AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), + nullable=False, index=True) + + IntendedWavelengthSpacingUnitsObj = relationship( + Units, + primaryjoin='SpectraResults.IntendedWavelengthSpacingUnitsID == Units.UnitsID' + ) + SpatialReferenceObj = relationship(SpatialReferences) + XLocationUnitsObj = relationship(Units, primaryjoin='SpectraResults.XLocationUnitsID == Units.UnitsID') + YLocationUnitsObj = relationship(Units, primaryjoin='SpectraResults.YLocationUnitsID == Units.UnitsID') + ZLocationUnitsObj = relationship(Units, primaryjoin='SpectraResults.ZLocationUnitsID == Units.UnitsID') + + __mapper_args__ = {'polymorphic_identity': 'Spectra coverage'} + + +class TimeSeriesResults(Results): + ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) + XLocation = Column('xlocation', Float(53)) + XLocationUnitsID = Column('xlocationunitsid', ForeignKey(Units.UnitsID)) + YLocation = Column('ylocation', Float(53)) + YLocationUnitsID = Column('ylocationunitsid', ForeignKey(Units.UnitsID)) + ZLocation = Column('zlocation', Float(53)) + ZLocationUnitsID = Column('zlocationunitsid', ForeignKey(Units.UnitsID)) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) + IntendedTimeSpacing = Column('intendedtimespacing', Float(53)) + IntendedTimeSpacingUnitsID = Column('intendedtimespacingunitsid', ForeignKey(Units.UnitsID)) + AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), + nullable=False, index=True) + + IntendedTimeSpacingUnitsObj = relationship( + Units, + primaryjoin='TimeSeriesResults.IntendedTimeSpacingUnitsID == Units.UnitsID' + ) + SpatialReferenceObj = relationship(SpatialReferences) + XLocationUnitsObj = relationship(Units, primaryjoin='TimeSeriesResults.XLocationUnitsID == Units.UnitsID') + YLocationUnitsObj = relationship(Units, primaryjoin='TimeSeriesResults.YLocationUnitsID == Units.UnitsID') + ZLocationUnitsObj = relationship(Units, primaryjoin='TimeSeriesResults.ZLocationUnitsID == Units.UnitsID') + + __mapper_args__ = {'polymorphic_identity': 'Time series coverage'} + + +class SectionResults(Results): + ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) + YLocation = Column('ylocation', Float(53)) + YLocationUnitsID = Column('ylocationunitsid', ForeignKey(Units.UnitsID)) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) + IntendedXSpacing = Column('intendedxspacing', Float(53)) + IntendedXSpacingUnitsID = Column('intendedxspacingunitsid', ForeignKey(Units.UnitsID)) + IntendedZSpacing = Column('intendedzspacing', Float(53)) + IntendedZSpacingUnitsID = Column('intendedzspacingunitsid', ForeignKey(Units.UnitsID)) + IntendedTimeSpacing = Column('intendedtimespacing', Float(53)) + IntendedTimeSpacingUnitsID = Column('intendedtimespacingunitsid', ForeignKey(Units.UnitsID)) + AggregationStatisticCV = Column( + 'aggregationstatisticcv', + ForeignKey(CVAggregationStatistic.Name), + nullable=False, + index=True + ) + + IntendedTimeSpacingUnitsObj = relationship( + Units, + primaryjoin='SectionResults.IntendedTimeSpacingUnitsID == Units.UnitsID' + ) + + IntendedXSpacingUnitsObj = relationship( + Units, + primaryjoin='SectionResults.IntendedXSpacingUnitsID == Units.UnitsID' + ) + + IntendedZSpacingUnitsObj = relationship( + Units, + primaryjoin='SectionResults.IntendedZSpacingUnitsID == Units.UnitsID' + ) + SpatialReferenceObj = relationship(SpatialReferences) + YLocationUnitsObj = relationship(Units, primaryjoin='SectionResults.YLocationUnitsID == Units.UnitsID') + + __mapper_args__ = {'polymorphic_identity': 'Section coverage'} + + +class TrajectoryResults(Results): + ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) + IntendedTrajectorySpacing = Column('intendedtrajectoryspacing', Float(53)) + IntendedTrajectorySpacingUnitsID = Column('intendedtrajectoryspacingunitsid', ForeignKey(Units.UnitsID)) + IntendedTimeSpacing = Column('intendedtimespacing', Float(53)) + IntendedTimeSpacingUnitsID = Column('intendedtimespacingunitsid', ForeignKey(Units.UnitsID)) + AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), + nullable=False, index=True) + + IntendedTimeSpacingUnitsObj = relationship( + Units, + primaryjoin='TrajectoryResults.IntendedTimeSpacingUnitsID == Units.UnitsID' + ) + IntendedTrajectorySpacingUnitsObj = relationship( + Units, + primaryjoin='TrajectoryResults.IntendedTrajectorySpacingUnitsID == Units.UnitsID' + ) + SpatialReferenceObj = relationship(SpatialReferences) + + __mapper_args__ = {'polymorphic_identity': 'Trajectory coverage'} + + +class MeasurementResults(Results): + ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) + XLocation = Column('xlocation', Float(53)) + XLocationUnitsID = Column('xlocationunitsid', ForeignKey(Units.UnitsID)) + YLocation = Column('ylocation', Float(53)) + YLocationUnitsID = Column('ylocationunitsid', ForeignKey(Units.UnitsID)) + ZLocation = Column('zlocation', Float(53)) + ZLocationUnitsID = Column('zlocationunitsid', ForeignKey(Units.UnitsID)) + SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) + CensorCodeCV = Column('censorcodecv', ForeignKey(CVCensorCode.Name), nullable=False, index=True) + QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) + AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), + nullable=False, index=True) + TimeAggregationInterval = Column('timeaggregationinterval', Float(53), nullable=False) + TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), + nullable=False) + + SpatialReferenceObj = relationship(SpatialReferences) + TimeAggregationIntervalUnitsObj = relationship( + Units, + primaryjoin='MeasurementResults.TimeAggregationIntervalUnitsID == Units.UnitsID' + ) + XLocationUnitsObj = relationship( + Units, + primaryjoin='MeasurementResults.XLocationUnitsID == Units.UnitsID' + ) + YLocationUnitsObj = relationship( + Units, + primaryjoin='MeasurementResults.YLocationUnitsID == Units.UnitsID' + ) + ZLocationUnitsObj = relationship( + Units, + primaryjoin='MeasurementResults.ZLocationUnitsID == Units.UnitsID' + ) + + __mapper_args__ = {'polymorphic_identity': 'Measurement'} + + +class CategoricalResultValues(Base): + ValueID = Column('valueid', BigIntegerType, primary_key=True) + ResultID = Column('resultid', ForeignKey(CategoricalResults.ResultID), nullable=False) + DataValue = Column('datavalue', String(255), nullable=False) + ValueDateTime = Column('valuedatetime', DateTimeType, nullable=False) + ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) + + ResultObj = relationship(CategoricalResults) + + +class MeasurementResultValues(Base): + ValueID = Column('valueid', BigIntegerType, primary_key=True) + ResultID = Column('resultid', ForeignKey(MeasurementResults.ResultID), nullable=False) + DataValue = Column('datavalue', Float(53), nullable=False) + ValueDateTime = Column('valuedatetime', DateTimeType, nullable=False) + ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) + + ResultObj = relationship(MeasurementResults) + + +class PointCoverageResultValues(Base): + ValueID = Column('valueid', BigIntegerType, primary_key=True) + ResultID = Column('resultid', ForeignKey(PointCoverageResults.ResultID), nullable=False) + DataValue = Column('datavalue', BigIntegerType, nullable=False) + ValueDateTime = Column('valuedatetime', DateTimeType, nullable=False) + ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) + XLocation = Column('xlocation', Float(53), nullable=False) + XLocationUnitsID = Column('xlocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + YLocation = Column('ylocation', Float(53), nullable=False) + YLocationUnitsID = Column('ylocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + CensorCodeCV = Column('censorcodecv', ForeignKey(CVCensorCode.Name), nullable=False, index=True) + QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) + + ResultObj = relationship(PointCoverageResults) + XLocationUnitsObj = relationship( + Units, + primaryjoin='PointCoverageResultValues.XLocationUnitsID == Units.UnitsID' + ) + YLocationUnitsobj = relationship( + Units, + primaryjoin='PointCoverageResultValues.YLocationUnitsID == Units.UnitsID' + ) + + +class ProfileResultValues(Base): + ValueID = Column('valueid', BigIntegerType, primary_key=True) + ResultID = Column('resultid', ForeignKey(ProfileResults.ResultID), nullable=False) + DataValue = Column('datavalue', Float(53), nullable=False) + ValueDateTime = Column('valuedatetime', DateTimeType, nullable=False) + ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) + ZLocation = Column('zlocation', Float(53), nullable=False) + ZAggregationInterval = Column('zaggregationinterval', Float(53), nullable=False) + ZLocationUnitsID = Column('zlocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + CensorCodeCV = Column('censorcodecv', ForeignKey(CVCensorCode.Name), nullable=False, index=True) + QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) + TimeAggregationInterval = Column('timeaggregationinterval', Float(53), nullable=False) + TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), + nullable=False) + + ResultObj = relationship(ProfileResults) + TimeAggregationIntervalUnitsObj = relationship( + Units, + primaryjoin='ProfileResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID' + ) + ZLocationUnitsObj = relationship( + Units, + primaryjoin='ProfileResultValues.ZLocationUnitsID == Units.UnitsID' + ) + + +class SectionResultValues(Base): + ValueID = Column('valueid', BigIntegerType, primary_key=True) + ResultID = Column('resultid', ForeignKey(SectionResults.ResultID), nullable=False) + DataValue = Column('datavalue', Float(53), nullable=False) + ValueDateTime = Column('valuedatetime', DateTimeType, nullable=False) + ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) + XLocation = Column('xlocation', Float(53), nullable=False) + XAggregationInterval = Column('xaggregationinterval', Float(53), nullable=False) + XLocationUnitsID = Column('xlocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + ZLocation = Column('zlocation', BigIntegerType, nullable=False) + ZAggregationInterval = Column('zaggregationinterval', Float(53), nullable=False) + ZLocationUnitsID = Column('zlocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + CensorCodeCV = Column('censorcodecv', ForeignKey(CVCensorCode.Name), nullable=False, index=True) + QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) + AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), + nullable=False, index=True) + TimeAggregationInterval = Column('timeaggregationinterval', Float(53), nullable=False) + TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), + nullable=False) + + ResultObj = relationship(SectionResults) + TimeAggregationIntervalUnitsObj = relationship( + Units, + primaryjoin='SectionResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID' + ) + XLocationUnitsObj = relationship( + Units, + primaryjoin='SectionResultValues.XLocationUnitsID == Units.UnitsID' + ) + ZLocationUnitsObj = relationship( + Units, + primaryjoin='SectionResultValues.ZLocationUnitsID == Units.UnitsID' + ) + + +class SpectraResultValues(Base): + ValueID = Column('valueid', BigIntegerType, primary_key=True) + ResultID = Column('resultid', ForeignKey(SpectraResults.ResultID), nullable=False) + DataValue = Column('datavalue', Float(53), nullable=False) + ValueDateTime = Column('valuedatetime', DateTimeType, nullable=False) + ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) + ExcitationWavelength = Column('excitationwavelength', Float(53), nullable=False) + EmissionWavelength = Column('emmistionwavelength', Float(53), nullable=False) + WavelengthUnitsID = Column('wavelengthunitsid', ForeignKey(Units.UnitsID), nullable=False) + CensorCodeCV = Column('censorcodecv', ForeignKey(CVCensorCode.Name), nullable=False, index=True) + QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) + TimeAggregationInterval = Column('timeaggregationinterval', Float(53), nullable=False) + TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), + nullable=False) + + ResultObj = relationship(SpectraResults) + TimeAggregationIntervalUnitsObj = relationship( + Units, + primaryjoin='SpectraResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID' + ) + + WavelengthUnitsObj = relationship( + Units, + primaryjoin='SpectraResultValues.WavelengthUnitsID == Units.UnitsID' + ) + + +class TimeSeriesResultValues(Base): + ValueID = Column('valueid', BigIntegerType, primary_key=True) + ResultID = Column('resultid', ForeignKey(TimeSeriesResults.ResultID), nullable=False) + DataValue = Column('datavalue', Float(53), nullable=False) + ValueDateTime = Column('valuedatetime', DateTimeType, nullable=False) + ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) + CensorCodeCV = Column('censorcodecv', ForeignKey(CVCensorCode.Name), nullable=False, index=True) + QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) + TimeAggregationInterval = Column('timeaggregationinterval', Float(53), nullable=False) + TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), + nullable=False) + + ResultObj = relationship(TimeSeriesResults) + TimeAggregationIntervalUnitsObj = relationship(Units) + + def get_columns(self): + return ['ValueID', 'ResultID', 'DataValue', 'ValueDateTime', 'ValueDateTimeUTCOffset', + 'CensorCodeCV', 'QualityCodeCV', 'TimeAggregationInterval', 'TimeAggregationIntervalUnitsID'] + + def list_repr(self): + return [self.ValueID, self.ResultID, self.DataValue, self.ValueDateTime, self.ValueDateTimeUTCOffset, + self.CensorCodeCV, self.QualityCodeCV, self.TimeAggregationInterval, + self.TimeAggregationIntervalUnitsID] + + +class TrajectoryResultValues(Base): + ValueID = Column('valueid', BigIntegerType, primary_key=True) + ResultID = Column('resultid', ForeignKey(TrajectoryResults.ResultID), nullable=False) + DataValue = Column('datavalue', Float(53), nullable=False) + ValueDateTime = Column('valuedatetime', DateTimeType, nullable=False) + ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) + XLocation = Column('xlocation', Float(53), nullable=False) + XLocationUnitsID = Column('xlocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + YLocation = Column('ylocation', Float(53), nullable=False) + YLocationUnitsID = Column('ylocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + ZLocation = Column('zlocation', Float(53), nullable=False) + ZLocationUnitsID = Column('zlocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + TrajectoryDistance = Column('trajectorydistance', Float(53), nullable=False) + TrajectoryDistanceAggregationInterval = Column( + 'trajectorydistanceaggregationinterval', + Float(53), + nullable=False + ) + TrajectoryDistanceUnitsID = Column('trajectorydistanceunitsid', Integer, nullable=False) + CensorCodeCV = Column('censorcodecv', ForeignKey(CVCensorCode.Name), nullable=False, index=True) + QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) + TimeAggregationInterval = Column('timeaggregationinterval', Float(53), nullable=False) + TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), + nullable=False) + + ResultObj = relationship(TrajectoryResults) + TimeAggregationIntervalUnitsObj = relationship( + Units, + primaryjoin='TrajectoryResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID' + ) + XLocationUnitsObj = relationship( + Units, + primaryjoin='TrajectoryResultValues.XLocationUnitsID == Units.UnitsID' + ) + YLocationUnitsObj = relationship( + Units, + primaryjoin='TrajectoryResultValues.YLocationUnitsID == Units.UnitsID' + ) + ZLocationUnitsObj = relationship( + Units, + primaryjoin='TrajectoryResultValues.ZLocationUnitsID == Units.UnitsID' + ) + + +class TransectResultValues(Base): + ValueID = Column('valueid', BigIntegerType, primary_key=True) + ResultID = Column('resultid', ForeignKey(TransectResults.ResultID), nullable=False) + DataValue = Column('datavalue', Float(53), nullable=False) + ValueDateTime = Column('valuedatetime', DateTimeType, nullable=False) + ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) + XLocation = Column('xlocation', Float(53), nullable=False) + XLocationUnitsID = Column('xlocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + YLocation = Column('ylocation', Float(53), nullable=False) + YLocationUnitsID = Column('ylocationunitsid', ForeignKey(Units.UnitsID), nullable=False) + TransectDistance = Column('transectdistance', Float(53), nullable=False) + TransectDistanceAggregationInterval = Column( + 'transectdistanceaggregationinterval', + Float(53), + nullable=False + ) + TransectDistanceUnitsID = Column('transectdistanceunitsid', ForeignKey(Units.UnitsID), nullable=False) + CensorCodeCV = Column('censorcodecv', ForeignKey(CVCensorCode.Name), nullable=False, index=True) + QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) + AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), + nullable=False, index=True) + TimeAggregationInterval = Column('timeaggregationinterval', Float(53), nullable=False) + TimeAggregationIntervalUnitsID = Column( + 'timeaggregationintervalunitsid', + ForeignKey(Units.UnitsID), + nullable=False + ) + + ResultObj = relationship(TransectResults) + TimeAggregationIntervalUnitsObj = relationship( + Units, + primaryjoin='TransectResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID' + ) + XLocationUnitsObj = relationship( + Units, + primaryjoin='TransectResultValues.XLocationUnitsID == Units.UnitsID' + ) + YLocationUnitsObj = relationship( + Units, + primaryjoin='TransectResultValues.YLocationUnitsID == Units.UnitsID' + ) + TransectDistanceUnitsObj = relationship( + Units, + primaryjoin='TransectResultValues.TransectDistanceUnitsID == Units.UnitsID' + ) + + +class CategoricalResultValueAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigIntegerType, ForeignKey(CategoricalResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + ValueObj = relationship(CategoricalResultValues) + + +class MeasurementResultValueAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigIntegerType, ForeignKey(MeasurementResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + ValueObj = relationship(MeasurementResultValues) + + +class PointCoverageResultValueAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigIntegerType, ForeignKey(PointCoverageResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + ValueObj = relationship(PointCoverageResultValues) + + +class ProfileResultValueAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigIntegerType, ForeignKey(ProfileResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + ValueObj = relationship(ProfileResultValues) + + +class SectionResultValueAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigIntegerType, ForeignKey(SectionResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + ValueObj = relationship(SectionResultValues) + + +class SpectraResultValueAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigIntegerType, ForeignKey(SpectraResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + ValueObj = relationship(SpectraResultValues) + + +class TimeSeriesResultValueAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigIntegerType, ForeignKey(TimeSeriesResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + ValueObj = relationship(TimeSeriesResultValues) + + +class TrajectoryResultValueAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigIntegerType, ForeignKey(TrajectoryResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + ValueObj = relationship(TrajectoryResultValues) + + +class TransectResultValueAnnotations(Base): + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigIntegerType, ForeignKey(TransectResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + ValueObj = relationship(TransectResultValues) + + +def _changeSchema(schema): + import inspect + import sys + # get a list of all of the classes in the module + clsmembers = inspect.getmembers(sys.modules[__name__], + lambda member: inspect.isclass(member) and member.__module__ == __name__) + + for name, Tbl in clsmembers: + import sqlalchemy.ext.declarative.api as api + + if isinstance(Tbl, api.DeclarativeMeta): + # check to see if the schema is already set correctly + if Tbl.__table__.schema == schema: + return + Tbl.__table__.schema = schema + Tbl.__table_args__['schema'] = schema + + +def _getSchema(engine): + from sqlalchemy.engine import reflection + + insp = reflection.Inspector.from_engine(engine) + for name in insp.get_schema_names(): + if 'odm2' == name.lower(): + return name + + return insp.default_schema_name + + +def setSchema(engine): + s = _getSchema(engine) + _changeSchema(s) diff --git a/odm2api/services/__init__.py b/odm2api/services/__init__.py new file mode 100644 index 0000000..620afca --- /dev/null +++ b/odm2api/services/__init__.py @@ -0,0 +1,15 @@ +from __future__ import (absolute_import, division, print_function) + +from odm2api.services.createService import CreateODM2 +from odm2api.services.deleteService import DeleteODM2 +from odm2api.services.readService import ReadODM2 +from odm2api.services.updateService import UpdateODM2 + +__author__ = 'jmeline' + +__all__ = [ + 'CreateODM2', + 'DeleteODM2', + 'ReadODM2', + 'UpdateODM2' +] diff --git a/odm2api/services/createService.py b/odm2api/services/createService.py new file mode 100644 index 0000000..3bae275 --- /dev/null +++ b/odm2api/services/createService.py @@ -0,0 +1,154 @@ +from __future__ import (absolute_import, division, print_function) + +import uuid + +from odm2api import serviceBase +from odm2api.models import TimeSeriesResultValues + +__author__ = 'sreeder' + + +class CreateODM2(serviceBase): + # Annotations + + def create(self, value): + self._session.add(value) + self._session.commit() + return value + + def createAll(self, values): + self._session.add_all(values) + self._session.commit() + return values + + def createVariable(self, var): + self._session.add(var) + self._session.commit() + + return var + + def createMethod(self, method): + self._session.add(method) + self._session.commit() + return method + + def createProcessingLevel(self, proclevel): + self._session.add(proclevel) + self._session.commit() + return proclevel + + def createSamplingFeature(self, samplingfeature): + if samplingfeature.SamplingFeatureUUID is None: + samplingfeature.SamplingFeatureUUID = str(uuid.uuid1()) + self._session.add(samplingfeature) + self._session.commit() + return samplingfeature + + def createUnit(self, unit): + self._session.add(unit) + self._session.commit() + return unit + + def createOrganization(self, org): + self._session.add(org) + self._session.commit() + return org + + def createPerson(self, person): + self._session.add(person) + self._session.commit() + return person + + def createAffiliation(self, affiliation): + self._session.add(affiliation) + self._session.commit() + return affiliation + + def createDataset(self, dataset): + self._session.add(dataset) + self._session.commit() + return dataset + + def createDatasetResults(self, datasetresult): + self._session.add(datasetresult) + self._session.commit() + return datasetresult + + def createAction(self, action): + self._session.add(action) + self._session.commit() + return action + + def createActionby(self, actionby): + + self._session.add(actionby) + self._session.commit() + return actionby + + def createFeatureAction(self, action): + self._session.add(action) + self._session.commit() + return action + + def createAnnotations(self, anno): + self._session.add(anno) + self._session.commit() + return anno + + def createRelatedAction(self, relatedaction): + self._session.add(relatedaction) + self._session.commit() + return relatedaction + + def createResult(self, result): + if result.ResultUUID is None: + result.ResultUUID = str(uuid.uuid1()) + self._session.add(result) + self._session.commit() + return result + + def createResultValue(self, value): + self._session.add(value) + self._session.commit() + self._session.flush() + return value + + def createSpatialReference(self, spatialref): + self._session.add(spatialref) + self._session.commit() + return spatialref + + def createModel(self, model): + self._session.add(model) + self._session.commit() + + return model + + def createRelatedModel(self, relatedmodel): + self._session.add(relatedmodel) + self._session.commit() + return relatedmodel + + def createSimulation(self, simulation): + self._session.add(simulation) + self._session.commit() + return simulation + + def createTimeSeriesResultValues(self, datavalues): + try: + # FXIME: F841 local variable 'tablename' is assigned to but never used. + # tablename = TimeSeriesResultValues.__tablename__ + datavalues.to_sql( + name='TimeSeriesResultValues', + schema=TimeSeriesResultValues.__table_args__['schema'], + if_exists='append', + chunksize=1000, + con=self._session_factory.engine, + index=False + ) + self._session.commit() + + return datavalues + except Exception as e: + print(e) + return None diff --git a/odm2api/services/deleteService.py b/odm2api/services/deleteService.py new file mode 100644 index 0000000..0f76d9c --- /dev/null +++ b/odm2api/services/deleteService.py @@ -0,0 +1,42 @@ +from __future__ import (absolute_import, division, print_function) + +from odm2api import serviceBase +from odm2api.models import TimeSeriesResultValues + + +__author__ = 'jmeline' + +# Annotations + + +class DeleteODM2(serviceBase): + + def remove(self, obj): + self._session.delete(obj) + +# CV +# Core +# Data Quality +# Equipment +# Extension Properties +# External Identifiers +# Lab Analyses +# Provenance +# Annotations +# Sampling Features +# Sensors +# Result Values + + def deleteTSRValues(self, ids=None, startdate=None, dates=None): + + q = self._session.query(TimeSeriesResultValues) + if ids: + q = q.filter(TimeSeriesResultValues.ResultID.in_(ids)) + if startdate: + # delete all values on or after the startdate. + q = q.filter(TimeSeriesResultValues.ValueDateTime >= startdate) + if dates: + q = q.filter(TimeSeriesResultValues.ValueDateTime.in_(dates)) + numvals = q.count() + q.delete(False) + return numvals diff --git a/odm2api/services/readService.py b/odm2api/services/readService.py new file mode 100644 index 0000000..e93a712 --- /dev/null +++ b/odm2api/services/readService.py @@ -0,0 +1,1503 @@ +from __future__ import (absolute_import, division, print_function) + +import warnings + +from odm2api import serviceBase +from odm2api.models import ( + ActionAnnotations, ActionDirectives, ActionExtensionPropertyValues, Actions, + Affiliations, Annotations, AuthorLists, CVActionType, CVAggregationStatistic, + CVAnnotationType, CVCensorCode, CVDataQualityType, CVDataSetType, CVDirectiveType, + CVElevationDatum, CVEquipmentType, CVMediumType, CVMethodType, CVOrganizationType, + CVPropertyDataType, CVQualityCode, CVRelationshipType, CVResultType, CVSamplingFeatureGeoType, + CVSamplingFeatureType, CVSiteType, CVSpatialOffsetType, CVSpeciation, CVSpecimenType, + CVStatus, CVTaxonomicClassifierType, CVUnitsType, CVVariableName, CVVariableType, + CalibrationActions, CalibrationReferenceEquipment, CalibrationStandards, + CategoricalResultValueAnnotations, CategoricalResultValues, CitationExtensionPropertyValues, + CitationExternalIdentifiers, DataLoggerFileColumns, DataLoggerFiles, DataLoggerProgramFiles, + DataQuality, DataSetCitations, DataSets, DataSetsResults, DerivationEquations, Directives, Equipment, + EquipmentActions, EquipmentAnnotations, EquipmentModels, EquipmentUsed, ExtensionProperties, + ExternalIdentifierSystems, FeatureActions, InstrumentOutputVariables, MaintenanceActions, + MeasurementResultValueAnnotations, MeasurementResultValues, MethodAnnotations, + MethodCitations, MethodExtensionPropertyValues, MethodExternalIdentifiers, + Methods, Models, Organizations, People, PersonExternalIdentifiers, + PointCoverageResultValueAnnotations, PointCoverageResultValues, ProcessingLevels, + ProfileResultValueAnnotations, ProfileResultValues, ReferenceMaterialExternalIdentifiers, + ReferenceMaterialValues, ReferenceMaterials, RelatedActions, RelatedAnnotations, + RelatedCitations, RelatedDataSets, RelatedEquipment, RelatedFeatures, RelatedModels, + RelatedResults, ResultAnnotations, ResultDerivationEquations, ResultExtensionPropertyValues, + ResultNormalizationValues, Results, ResultsDataQuality, SamplingFeatureAnnotations, + SamplingFeatureExtensionPropertyValues, SamplingFeatureExternalIdentifiers, + SamplingFeatures, SectionResultValueAnnotations, SectionResults, Simulations, + SpatialReferenceExternalIdentifiers, SpatialReferences, SpecimenBatchPositions, + SpectraResultValueAnnotations, SpectraResultValues, TaxonomicClassifierExternalIdentifiers, + TaxonomicClassifiers, TimeSeriesResultValueAnnotations, TimeSeriesResultValues, + TrajectoryResultValueAnnotations, TrajectoryResultValues, + TransectResultValueAnnotations, TransectResultValues, Units, VariableExtensionPropertyValues, + VariableExternalIdentifiers, Variables, +) + +import pandas as pd + +from sqlalchemy import distinct, exists +from sqlalchemy.orm import contains_eager + +__author__ = 'sreeder' + + +class DetailedResult: + def __init__(self, action, result, + sc, sn, + method, variable, + processingLevel, + unit): + # result.result_id etc. + self.ResultID = result.ResultID + self.SamplingFeatureCode = sc + self.MethodCode = method.MethodCode + self.VariableCode = variable.VariableCode + self.ProcessingLevelCode = processingLevel.ProcessingLevelCode + self.UnitsName = unit.UnitsName + + self.SamplingFeatureName = sn + self.MethodName = method.MethodName + self.VariableNameCV = variable.VariableNameCV + self.ProcessingLevelDefinition = processingLevel.Definition + self.ValueCount = result.ValueCount + self.BeginDateTime = action.BeginDateTime + self.EndDateTime = action.EndDateTime + self.ResultObj = result + + +class DetailedAffiliation: + def __init__(self, affiliation, person, org): + self.AffiliationID = affiliation.AffiliationID + self.Name = person.PersonFirstName + ' ' + person.PersonLastName + self.Organization = '(' + org.OrganizationCode + ') ' + org.OrganizationName + + +class SamplingFeatureDataSet(): + datasets = {} + related_features = {} + + def __init__(self, samplingfeature, datasetresults, relatedfeatures): + sf = samplingfeature + + self.SamplingFeatureID = sf.SamplingFeatureID + self.SamplingFeatureUUID = sf.SamplingFeatureUUID + self.SamplingFeatureTypeCV = sf.SamplingFeatureTypeCV + self.SamplingFeatureCode = sf.SamplingFeatureCode + self.SamplingFeatureName = sf.SamplingFeatureName + self.SamplingFeatureDescription = sf.SamplingFeatureDescription + self.SamplingFeatureGeotypeCV = sf.SamplingFeatureGeotypeCV + self.Elevation_m = sf.Elevation_m + self.ElevationDatumCV = sf.ElevationDatumCV + self.FeatureGeometryWKT = sf.FeatureGeometryWKT + self.assignDatasets(datasetresults) + self.assignRelatedFeatures(relatedfeatures) + + print(self.datasets) + + def assignDatasets(self, datasetresults): + self.datasets = {} + if datasetresults: + for dsr in datasetresults: + if dsr.DataSetObj not in self.datasets: + # if the dataset is not in the dictionary, add it and the first result + self.datasets[dsr.DataSetObj] = [] + res = dsr.ResultObj + # res.FeatureActionObj = None + self.datasets[dsr.DataSetObj].append(res) + else: + # if the dataset is in the dictionary, append the result object to the list + res = dsr.ResultObj + # res.FeatureActionObj = None + self.datasets[dsr.DataSetObj].append(res) + + def assignRelatedFeatures(self, relatedfeatures): + self.related_features = {} + if relatedfeatures: + for related in relatedfeatures: + if related.SamplingFeatureTypeCV == 'Site': + self.related_features = related + + +class ReadODM2(serviceBase): + def _get_columns(self, model): + """Internal helper function to get a dictionary of a model column properties. + + Args: + model (object): Sqlalchemy object, Ex. ODM2 model. + + Returns: + dict: Dictionary of column properties Ex. {'resultid': 'ResultID'} + + """ + from sqlalchemy.orm.properties import ColumnProperty + columns = [(prop.key.lower(), prop.key) for prop in model.__mapper__.iterate_properties if + isinstance(prop, ColumnProperty)] + + return dict(columns) + + def _check_kwargs(self, args, kwargs): + """Internal helper function to check for unused keyword arguments + + Args: + args (list): List of expected, valid arguments. + kwargs (dict): Dictionary of keyword arguments from user + Returns: + None + """ + invkwd = filter(lambda x: x not in args, kwargs.keys()) + if invkwd: + warnings.warn('Got unexpected keyword argument(s) {}'.format(','.join(invkwd)), stacklevel=2) + + # Exists functions + def resultExists(self, result): + """ + Check to see if a Result Object exists + * Pass Result Object - return a boolean value of wether the given object exists + + """ + try: + + ret = self._session.query(exists().where(Results.ResultTypeCV == result.ResultTypeCV) + .where(Results.VariableID == result.VariableID) + .where(Results.UnitsID == result.UnitsID) + .where(Results.ProcessingLevelID == result.ProcessingLevelID) + .where(Results.SampledMediumCV == result.SampledMediumCV) + ) + return ret.scalar() + + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Annotations + def getAnnotations(self, annottype=None, codes=None, ids=None, **kwargs): + """ + * Pass Nothing - return a list of all objects + * Pass AnnotationTypeCV - return a list of all objects of the fiven type + * Pass a list of codes - return a list of objects, one for each of the given codes + * Pass a list of ids -return a list of objects, one for each of the given ids + + """ + # TODO What keywords do I use for type. + a = Annotations + self._check_kwargs(['type'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the annottype parameter instead.', + DeprecationWarning, stacklevel=2) + annottype = kwargs['type'] + if annottype: + if annottype == 'action': + a = ActionAnnotations + elif annottype == 'categoricalresultvalue': + a = CategoricalResultValueAnnotations + elif annottype == 'equipmentannotation': + a = EquipmentAnnotations + elif annottype == 'measurementresultvalue': + a = MeasurementResultValueAnnotations + elif annottype == 'method': + a = MethodAnnotations + elif annottype == 'pointcoverageresultvalue': + a = PointCoverageResultValueAnnotations + elif annottype == 'profileresultvalue': + a = ProfileResultValueAnnotations + elif annottype == 'result': + a = ResultAnnotations + elif annottype == 'samplingfeature': + a = SamplingFeatureAnnotations + elif annottype == 'sectionresultvalue': + a = SectionResultValueAnnotations + elif annottype == 'spectraresultvalue': + a = SpectraResultValueAnnotations + elif annottype == 'timeseriesresultvalue': + a = TimeSeriesResultValueAnnotations + elif annottype == 'trajectoryresultvalue': + a = TrajectoryResultValueAnnotations + elif annottype == 'transectresultvalue': + a = TransectResultValueAnnotations + try: + query = self._session.query(a) + if codes: + query = query.filter(Annotations.AnnotationCode.in_(codes)) + if ids: + query = query.filter(Annotations.AnnotationID.in_(ids)) + return query.all() + + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # CV + def getCVs(self, cvtype, **kwargs): + """ + getCVs(self, type): + * Pass CVType - return a list of all objects of the given type + + """ + self._check_kwargs(['type'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the cvtype parameter instead.', + DeprecationWarning, stacklevel=2) + cvtype = kwargs['type'] + + if cvtype == 'actiontype': + CV = CVActionType + elif cvtype == 'aggregationstatistic': + CV = CVAggregationStatistic + elif cvtype == 'annotationtype': + CV = CVAnnotationType + elif cvtype == 'censorcode': + CV = CVCensorCode + elif cvtype == 'dataqualitytype': + CV = CVDataQualityType + elif cvtype == 'dataset type': + CV = CVDataSetType + elif cvtype == 'Directive Type': + CV = CVDirectiveType + elif cvtype == 'Elevation Datum': + CV = CVElevationDatum + elif cvtype == 'Equipment Type': + CV = CVEquipmentType + elif cvtype == 'Medium': + CV = CVMediumType + elif cvtype == 'Method Type': + CV = CVMethodType + elif cvtype == 'Organization Type': + CV = CVOrganizationType + elif cvtype == 'Property Data Type': + CV = CVPropertyDataType + elif cvtype == 'Quality Code': + CV = CVQualityCode + elif cvtype == 'Relationship Type': + CV = CVRelationshipType + elif cvtype == 'Result Type': + CV = CVResultType + elif cvtype == 'Sampling Feature Geo-type': + CV = CVSamplingFeatureGeoType + elif cvtype == 'Sampling Feature Type': + CV = CVSamplingFeatureType + elif cvtype == 'Site Type': + CV = CVSiteType + elif cvtype == 'Spatial Offset Type': + CV = CVSpatialOffsetType + elif cvtype == 'Speciation': + CV = CVSpeciation + elif cvtype == 'Specimen Type': + CV = CVSpecimenType + elif cvtype == 'Status': + CV = CVStatus + elif cvtype == 'Taxonomic Classifier Type': + CV = CVTaxonomicClassifierType + elif cvtype == 'Units Type': + CV = CVUnitsType + elif cvtype == 'Variable Name': + CV = CVVariableName + elif cvtype == 'Variable Type': + CV = CVVariableType + else: + return None + try: + return self._session.query(CV).all() + except Exception as e: + print('Error running Query: {}'.format(e)) + + # Core + def getDetailedAffiliationInfo(self): + """ + * Pass Nothing - Return a list of all Affiliations with detailed information, + including Affiliation, People and Organization + + """ + q = self._session.query(Affiliations, People, Organizations) \ + .filter(Affiliations.PersonID == People.PersonID) \ + .filter(Affiliations.OrganizationID == Organizations.OrganizationID) + affiliationList = [] + for a, p, o in q.all(): + detailedAffiliation = DetailedAffiliation(a, p, o) + affiliationList.append(detailedAffiliation) + return affiliationList + + def getDetailedResultInfo(self, resultTypeCV=None, resultID=None, sfID=None): + # TODO can this be done by just getting the result object and drilling down? + # What is the performance comparison. + """ + Get detailed information for all selected Results including , unit info, site info, + method info , ProcessingLevel info. + * Pass nothing - return a list of all objects + * Pass resultTypeCV - All objects of given type + * Pass a result ID - single object with the given result ID + * Pass a SamplingFeatureID - All objects associated with the given sampling feature. + + """ + q = self._session.query( + Actions, + Results, + SamplingFeatures.SamplingFeatureCode, + SamplingFeatures.SamplingFeatureName, + Methods, + Variables, + ProcessingLevels, + Units).filter(Results.VariableID == Variables.VariableID) \ + .filter(Results.UnitsID == Units.UnitsID) \ + .filter(Results.FeatureActionID == FeatureActions.FeatureActionID) \ + .filter(FeatureActions.SamplingFeatureID == SamplingFeatures.SamplingFeatureID) \ + .filter(FeatureActions.ActionID == Actions.ActionID) \ + .filter(Actions.MethodID == Methods.MethodID) \ + .filter(Results.ProcessingLevelID == ProcessingLevels.ProcessingLevelID) \ + .filter(Results.ResultTypeCV == resultTypeCV) \ + .order_by(Results.ResultID) + resultList = [] + if sfID: + q = q.filter(SamplingFeatures.SamplingFeatureID == sfID) + if resultID: + q = q.filter(Results.ResultID == resultID) + + for a, r, sc, sn, m, v, p, u in q.all(): + detailedResult = DetailedResult( + a, r, sc, sn, m, v, p, u + ) + resultList.append(detailedResult) + return resultList + + # Taxonomic Classifiers + def getTaxonomicClassifiers(self): + """ + getTaxonomicClassifiers(self): + * Pass nothing - return a list of all objects + + """ + return self._session.query(TaxonomicClassifiers).all() + + # Variable + def getVariables(self, ids=None, codes=None, sitecode=None, results=False): + """ + * Pass nothing - returns full list of variable objects + * Pass a list of VariableID - returns a single variable object + * Pass a list of VariableCode - returns a single variable object + * Pass a SiteCode - returns a list of Variable objects that are collected at the given site. + * Pass whether or not you want to return the sampling features that have results associated with them + + """ + if sitecode: + try: + variables = [ + x[0] for x in + self._session.query(distinct(Results.VariableID)) + .filter(Results.FeatureActionID == FeatureActions.FeatureActionID) + .filter(FeatureActions.SamplingFeatureID == SamplingFeatures.SamplingFeatureID) + .filter(SamplingFeatures.SamplingFeatureCode == sitecode).all() + ] + if ids: + ids = list(set(ids).intersection(variables)) + else: + ids = variables + except Exception as e: + print('Error running Query: {}'.format(e)) + pass + + if results: + try: + variables = [x[0] for x in self._session.query(distinct(Results.VariableID)).all()] + if ids: + ids = list(set(ids).intersection(variables)) + else: + ids = variables + except Exception as e: + print('Error running Query: {}'.format(e)) + pass + + query = self._session.query(Variables) + if ids: + query = query.filter(Variables.VariableID.in_(ids)) + if codes: + query = query.filter(Variables.VariableCode.in_(codes)) + try: + return query.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Method + def getMethods(self, ids=None, codes=None, methodtype=None, **kwargs): + """ + * Pass nothing - returns full list of method objects + * Pass a list of MethodIDs - returns a single method object for each given id + * Pass a list of MethodCode - returns a single method object for each given code + * Pass a MethodType - returns a list of method objects of the given MethodType + + """ + self._check_kwargs(['type'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the medtype parameter instead.', + DeprecationWarning, stacklevel=2) + methodtype = kwargs['type'] + + q = self._session.query(Methods) + if ids: + q = q.filter(Methods.MethodID.in_(ids)) + if codes: + q = q.filter(Methods.MethodCode.in_(codes)) + if methodtype: + q = q.filter_by(MethodTypeCV=methodtype) + + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # ProcessingLevel + def getProcessingLevels(self, ids=None, codes=None): + """ + Retrieve a list of Processing Levels + + If no arguments are passed to the function, or their values are None, + all Processing Levels objects in the database will be returned. + + Args: + ids (list, optional): List of Processing Levels IDs. + codes (list, optional): List of Processing Levels Codes. + + + Returns: + list: List of ProcessingLevels Objects + + Examples: + >>> READ = ReadODM2(SESSION_FACTORY) + >>> READ.getProcessingLevels(ids=[1, 3]) + >>> READ.getProcessingLevels(codes=['L1', 'L3']) + + """ + q = self._session.query(ProcessingLevels) + if ids: + q = q.filter(ProcessingLevels.ProcessingLevelID.in_(ids)) + if codes: + q = q.filter(ProcessingLevels.ProcessingLevelCode.in_(codes)) + + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Sampling Feature + def getSamplingFeatures(self, ids=None, codes=None, uuids=None, + sftype=None, wkt=None, results=False, **kwargs): + """Retrieve a list of Sampling Feature objects. + + If no arguments are passed to the function, or their values are None, + all Sampling Feature objects in the database will be returned. + + Args: + ids (list, optional): List of SamplingFeatureIDs. + codes (list, optional): List of SamplingFeature Codes. + uuids (list, optional): List of UUIDs string. + sftype (str, optional): Type of Sampling Feature from + `controlled vocabulary name `_. + wkt (str, optional): SamplingFeature Well Known Text. + results (bool, optional): Whether or not you want to return only the + sampling features that have results associated with them. + + Returns: + list: List of Sampling Feature objects + + Examples: + >>> READ = ReadODM2(SESSION_FACTORY) + >>> READ.getSamplingFeatures(ids=[39, 40]) + >>> READ.getSamplingFeatures(codes=['HOME', 'FIELD']) + >>> READ.getSamplingFeatures(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', + ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) + >>> READ.getSamplingFeatures(type='Site') + >>> READ.getSamplingFeatures(wkt='POINT (30 10)') + >>> READ.getSamplingFeatures(results=True) + >>> READ.getSamplingFeatures(type='Site', results=True) + + """ + self._check_kwargs(['type'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the sftype parameter instead.', + DeprecationWarning, stacklevel=2) + sftype = kwargs['type'] + if results: + try: + fas = [x[0] for x in self._session.query(distinct(Results.FeatureActionID)).all()] + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + sf = [x[0] for x in self._session.query(distinct(FeatureActions.SamplingFeatureID)).filter(FeatureActions.FeatureActionID.in_(fas)).all()] # noqa + if ids: + ids = list(set(ids).intersection(sf)) + else: + ids = sf + + q = self._session.query(SamplingFeatures) + + if sftype: + q = q.filter_by(SamplingFeatureTypeCV=sftype) + if ids: + q = q.filter(SamplingFeatures.SamplingFeatureID.in_(ids)) + if codes: + q = q.filter(SamplingFeatures.SamplingFeatureCode.in_(codes)) + if uuids: + q = q.filter(SamplingFeatures.SamplingFeatureUUID.in_(uuids)) + if wkt: + q = q.filter_by(FeatureGeometryWKT=wkt) + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + def getRelatedSamplingFeatures(self, sfid=None, rfid=None, relationshiptype=None): + # TODO: add functionality to filter by code + """ + * Pass a SamplingFeatureID - get a list of sampling feature objects + related to the input sampling feature + * Pass a RelatedFeatureID - get a list of Sampling features objects through the related feature + * Pass a RelationshipTypeCV - get a list of sampling feature objects with the given type + + """ + + sf = self._session.query(distinct(SamplingFeatures.SamplingFeatureID)) \ + .select_from(RelatedFeatures) + + if sfid: + sf = sf.join(RelatedFeatures.RelatedFeatureObj).filter(RelatedFeatures.SamplingFeatureID == sfid) + if rfid: + sf = sf.join(RelatedFeatures.SamplingFeatureObj).filter(RelatedFeatures.RelatedFeatureID == rfid) + if relationshiptype: + sf = sf.filter(RelatedFeatures.RelationshipTypeCV == relationshiptype) + try: + sfids = [x[0] for x in sf.all()] + if len(sfids) > 0: + sflist = self.getSamplingFeatures(ids=sfids) + return sflist + + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Action + def getActions(self, ids=None, acttype=None, sfid=None, **kwargs): + """ + * Pass nothing - returns a list of all Actions + * Pass a list of Action ids - returns a list of Action objects + * Pass a ActionTypeCV - returns a list of Action objects of that type + * Pass a SamplingFeature ID - returns a list of Action objects + associated with that Sampling feature ID, Found through featureAction table + + """ + self._check_kwargs(['type'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the acttype parameter instead.', + DeprecationWarning, stacklevel=2) + acttype = kwargs['type'] + a = Actions + if acttype == 'equipment': + a = EquipmentActions + elif acttype == 'calibration': + a = CalibrationActions + elif acttype == 'maintenance': + a = MaintenanceActions + + q = self._session.query(a) + if ids: + q = q.filter(a.ActionID.in_(ids)) + if sfid: + q = q.join(FeatureActions).filter(FeatureActions.SamplingFeatureID == sfid) + + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + def getRelatedActions(self, actionid=None): + """ + * Pass an ActionID - get a list of Action objects related to the input + action along with the relationship type + + """ + + q = self._session.query(Actions).select_from(RelatedActions).join(RelatedActions.RelatedActionObj) + if actionid: + q = q.filter(RelatedActions.ActionID == actionid) + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Unit + def getUnits(self, ids=None, name=None, unittype=None, **kwargs): + """ + * Pass nothing - returns a list of all units objects + * Pass a list of UnitsID - returns a single units object for the given id + * Pass UnitsName - returns a single units object + * Pass a type- returns a list of all objects of the given type + + """ + self._check_kwargs(['type'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the unittype parameter instead.', + DeprecationWarning, stacklevel=2) + unittype = kwargs['type'] + q = self._session.query(Units) + if ids: + q = q.filter(Units.UnitsID.in_(ids)) + if name: + q = q.filter(Units.UnitsName.ilike(name)) + if unittype: + q = q.filter(Units.UnitsTypeCV.ilike(unittype)) + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Organization + def getOrganizations(self, ids=None, codes=None): + """ + * Pass nothing - returns a list of all organization objects + * Pass a list of OrganizationID - returns a single organization object + * Pass a list of OrganizationCode - returns a single organization object + + """ + q = self._session.query(Organizations) + if ids: + q = q.filter(Organizations.OrganizationID.in_(ids)) + if codes: + q = q.filter(Organizations.OrganizationCode.in_(codes)) + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Person + def getPeople(self, ids=None, firstname=None, lastname=None): + """ + * Pass nothing - returns a list of all People objects + * Pass a list of PeopleID - returns a single People object + * Pass a First Name - returns a single People object + * Pass a Last Name - returns a single People object + + """ + q = self._session.query(People) + if ids: + q = q.filter(People.PersonID.in_(ids)) + if firstname: + q = q.filter(People.PersonFirstName.ilike(firstname)) + if lastname: + q = q.filter(People.PersonLastName.ilike(lastname)) + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + def getAffiliations(self, ids=None, personfirst=None, personlast=None, orgcode=None): + """Retrieve a list of Affiliation objects. + + If no arguments are passed to the function, or their values are None, + all Affiliation objects in the database will be returned. + + Args: + ids (list, optional): List of AffiliationIDs. + personfirst (str, optional): Person First Name. + personlast (str, optional): Person Last Name. + orgcode (str, optional): Organization Code. + + Returns: + list: List of Affiliation objects + + Examples: + >>> ReadODM2.getAffiliations(ids=[39,40]) + >>> ReadODM2.getAffiliations(personfirst='John', + ... personlast='Smith') + >>> ReadODM2.getAffiliations(orgcode='Acme') + + """ + q = self._session.query(Affiliations) + + if ids: + q = q.filter(Affiliations.AffiliationID.in_(ids)) + if orgcode: + q = q.join(Affiliations.OrganizationObj).filter(Organizations.OrganizationCode.ilike(orgcode)) + if personfirst: + q = q.join(Affiliations.PersonObj).filter(People.PersonFirstName.ilike(personfirst)) + if personlast: + q = q.join(Affiliations.PersonObj).filter(People.PersonLastName.ilike(personlast)) + + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Results + def getResults(self, ids=None, restype=None, uuids=None, actionid=None, simulationid=None, + variableid=None, siteid=None, sfids=None, sfuuids=None, sfcodes=None, **kwargs): + + # TODO what if user sends in both type and actionid vs just actionid + """Retrieve a list of Result objects. + + If no arguments are passed to the function, or their values are None, + all Result objects in the database will be returned. + + Args: + ids (list, optional): List of ResultIDs. + restype (str, optional): Type of Result from + `controlled vocabulary name `_. + uuids (list, optional): List of UUIDs string. + actionid (int, optional): ActionID. + simulationid (int, optional): SimulationID. + 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(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) + >>> ReadODM2.getResults(siteid=6) + >>> ReadODM2.getResults(variableid=7) + >>> ReadODM2.getResults(actionid=20) + + """ + query = self._session.query(Results) + self._check_kwargs(['type', 'sfid'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the restype parameter instead.', + DeprecationWarning, stacklevel=2) + restype = kwargs['type'] + if restype: + query = query.filter_by(ResultTypeCV=restype) + if variableid: + query = query.filter_by(VariableID=variableid) + if ids: + query = query.filter(Results.ResultID.in_(ids)) + if uuids: + query = query.filter(Results.ResultUUID.in_(uuids)) + if simulationid: + query = query.join(FeatureActions) \ + .join(Actions) \ + .join(Simulations) \ + .filter_by(SimulationID=simulationid) + if actionid: + query = query.join(FeatureActions).filter_by(ActionID=actionid) + if 'sfid' in kwargs: + warnings.warn('The parameter \'sfid\' is deprecated. ' + 'Please use the sfids parameter instead and send in a list.', + DeprecationWarning, stacklevel=2) + if kwargs['sfid']: + query = query.join(FeatureActions).filter_by(SamplingFeatureID=kwargs['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) + .join(RelatedFeatures.SamplingFeatureObj) + .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: + return query.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Datasets + def getDataSets(self, ids=None, codes=None, uuids=None, dstype=None): + """ + Retrieve a list of Datasets + + Args: + ids (list, optional): List of DataSetsIDs. + codes (list, optional): List of DataSet Codes. + uuids (list, optional): List of Dataset UUIDs string. + dstype (str, optional): Type of Dataset from + `controlled vocabulary name `_. + + + Returns: + list: List of DataSets Objects + + Examples: + >>> READ = ReadODM2(SESSION_FACTORY) + >>> READ.getDataSets(ids=[39, 40]) + >>> READ.getDataSets(codes=['HOME', 'FIELD']) + >>> READ.getDataSets(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', + ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) + >>> READ.getDataSets(dstype='singleTimeSeries') + + """ + q = self._session.query(DataSets) + if ids: + q = q.filter(DataSets.DataSetID.in_(ids)) + if codes: + q = q.filter(DataSets.DataSetCode.in_(codes)) + if uuids: + q.filter(DataSets.DataSetUUID.in_(uuids)) + if dstype: + q = q.filter(DataSets.DataSetTypeCV == dstype) + try: + return q.all() + except Exception as e: + print('Error running Query {}'.format(e)) + return None + + # Datasets + + def getDataSetsResults(self, ids=None, codes=None, uuids=None, dstype=None): + """ + Retrieve a detailed list of Datasets along with detailed metadata about the datasets + and the results contained within them + + **Must specify either DataSetID OR DataSetUUID OR DataSetCode)** + Args: + ids (list, optional): List of DataSetsIDs. + codes (list, optional): List of DataSet Codes. + uuids (list, optional): List of Dataset UUIDs string. + dstype (str, optional): Type of Dataset from + `controlled vocabulary name `_. + + + Returns: + list: List of DataSetsResults Objects + + Examples: + >>> READ = ReadODM2(SESSION_FACTORY) + >>> READ.getDataSetsResults(ids=[39, 40]) + >>> READ.getDataSetsResults(codes=['HOME', 'FIELD']) + >>> READ.getDataSetsResults(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', + ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) + >>> READ.getDataSetsResults(dstype='singleTimeSeries') + + """ + + # make sure one of the three arguments has been sent in + if all(v is None for v in [ids, codes, uuids]): + raise ValueError('Expected DataSetID OR DataSetUUID OR DataSetCode argument') + + q = self._session.query(DataSetsResults) \ + .join(DataSets) + if ids: + q = q.filter(DataSets.DataSetID.in_(ids)) + if codes: + q = q.filter(DataSets.DataSetCode.in_(codes)) + if uuids: + q.filter(DataSets.DataSetUUID.in_(uuids)) + if dstype: + q = q.filter(DataSets.DataSetTypeCV == dstype) + try: + return q.all() + except Exception as e: + print('Error running Query {}'.format(e)) + return None + + def getDataSetsValues(self, ids=None, codes=None, uuids=None, dstype=None, lowercols=True): + """ + Retrieve a list of datavalues associated with the given dataset info + + **Must specify either DataSetID OR DataSetUUID OR DataSetCode)** + Args: + ids (list, optional): List of DataSetsIDs. + codes (list, optional): List of DataSet Codes. + uuids (list, optional): List of Dataset UUIDs string. + dstype (str, optional): Type of Dataset from + `controlled vocabulary name `_. + lowercols (bool, optional): Make column names to be lowercase. + Default to True. + **Please start upgrading your code to rely on CamelCase column names, + In a near-future release, + the default will be changed to False, + and later the parameter may be removed**. + + + Returns: + list: List of Result Values Objects + + Examples: + >>> READ = ReadODM2(SESSION_FACTORY) + >>> READ.getDataSetsValues(ids=[39, 40]) + >>> READ.getDataSetsValues(codes=['HOME', 'FIELD']) + >>> READ.getDataSetsValues(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', + ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) + >>> READ.getDataSetsValues(dstype='singleTimeSeries', lowercols=False) + + """ + + dsr = self.getDataSetsResults(ids, codes, uuids, dstype) + + resids = [] + for ds in dsr: + resids.append(ds.ResultID) + + try: + return self.getResultValues(resultids=resids, lowercols=lowercols) + except Exception as e: + print('Error running Query {}'.format(e)) + return None + + def getSamplingFeatureDatasets(self, ids=None, codes=None, uuids=None, dstype=None, sftype=None): + """ + Retrieve a list of Datasets associated with the given sampling feature data. + + **Must specify either samplingFeatureID OR samplingFeatureUUID OR samplingFeatureCode)** + + Args: + ids (list, optional): List of SamplingFeatureIDs. + codes (list, optional): List of SamplingFeature Codes. + uuids (list, optional): List of UUIDs string. + dstype (str, optional): Type of Dataset from + `controlled vocabulary name `_. + sftype (str, optional): Type of SamplingFeature from + `controlled vocabulary name `_. + + Returns: + list: List of DataSetsResults Objects associated with the given sampling feature + + Examples: + >>> READ = ReadODM2(SESSION_FACTORY) + >>> READ.getSamplingFeatureDatasets(ids=[39, 40]) + >>> READ.getSamplingFeatureDatasets(codes=['HOME', 'FIELD']) + >>> READ.getSamplingFeatureDatasets(uuids=['a6f114f1-5416-4606-ae10-23be32dbc202', + ... '5396fdf3-ceb3-46b6-aaf9-454a37278bb4']) + >>> READ.getSamplingFeatureDatasets(dstype='singleTimeSeries') + >>> READ.getSamplingFeatureDatasets(sftype='Specimen') + + """ + + # make sure one of the three arguments has been sent in + if all(v is None for v in [ids, codes, uuids, sftype]): + raise ValueError( + 'Expected samplingFeatureID OR samplingFeatureUUID ' + 'OR samplingFeatureCode OR samplingFeatureType ' + 'argument') + + sf_query = self._session.query(SamplingFeatures) + if sftype: + sf_query = sf_query.filter(SamplingFeatures.SamplingFeatureTypeCV == sftype) + if ids: + sf_query = sf_query.filter(SamplingFeatures.SamplingFeatureID.in_(ids)) + if codes: + sf_query = sf_query.filter(SamplingFeatures.SamplingFeatureCode.in_(codes)) + if uuids: + sf_query = sf_query.filter(SamplingFeatures.SamplingFeatureUUID.in_(uuids)) + + sf_list = [] + for sf in sf_query.all(): + sf_list.append(sf) + + try: + sfds = [] + for sf in sf_list: + + # Eager loading the data. + q = self._session.query(DataSetsResults)\ + .join(DataSetsResults.ResultObj)\ + .join(Results.FeatureActionObj)\ + .filter(FeatureActions.SamplingFeatureID == sf.SamplingFeatureID)\ + .options(contains_eager(DataSetsResults.ResultObj) + .contains_eager(Results.FeatureActionObj) + .load_only(FeatureActions.SamplingFeatureID)) + + if dstype: + q = q.filter_by(DatasetTypeCV=dstype) + + vals = q.all() + + related = self.getRelatedSamplingFeatures(sf.SamplingFeatureID) + + sfds.append(SamplingFeatureDataSet(sf, vals, related)) + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + return sfds + + # Data Quality + def getDataQuality(self): + """ + * Pass nothing - return a list of all objects + """ + return self._session.query(DataQuality).all() + + # TODO DataQuality Schema Queries + def getReferenceMaterials(self): + """ + * Pass nothing - return a list of all objects + """ + return self._session.query(ReferenceMaterials).all() + + def getReferenceMaterialValues(self): + """ + * Pass nothing - return a list of all objects + """ + return self._session.query(ReferenceMaterialValues).all() + + def getResultNormalizationValues(self): + """ + * Pass nothing - return a list of all objects + """ + return self._session.query(ResultNormalizationValues).all() + + def getResultsDataQuality(self): + """ + * Pass nothing - return a list of all objects + """ + return self._session.query(ResultsDataQuality).all() + + # TODO Equipment Schema Queries + # Equipment + def getEquipment(self, codes=None, equiptype=None, sfid=None, actionid=None, **kwargs): + """ + * Pass nothing - returns a list of all Equipment objects + * Pass a list of EquipmentCodes- return a list of all Equipment objects that match each of the codes + * Pass a EquipmentType - returns a single Equipment object + * Pass a SamplingFeatureID - returns a single Equipment object + * Pass an ActionID - returns a single Equipment object + + """ + self._check_kwargs(['type'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the equiptype parameter instead.', + DeprecationWarning, stacklevel=2) + equiptype = kwargs['type'] + + # NOTE: Equiptype currently unused! + if equiptype: + pass + e = self._session.query(Equipment) + if sfid: + e = e.join(EquipmentUsed) \ + .join(Actions) \ + .join(FeatureActions) \ + .filter(FeatureActions.SamplingFeatureID == sfid) + if codes: + e = e.filter(Equipment.EquipmentCode.in_(codes)) + if actionid: + e = e.join(EquipmentUsed).join(Actions) \ + .filter(Actions.ActionID == actionid) + return e.all() + + def CalibrationReferenceEquipment(self): + """ + * Pass nothing - return a list of all objects + + """ + return self._session.query(CalibrationReferenceEquipment).all() + + def CalibrationStandards(self): + """ + * Pass nothing - return a list of all objects + + """ + return self._session.query(CalibrationStandards).all() + + def DataloggerFileColumns(self): + """ + * Pass nothing - return a list of all objects + + """ + return self._session.query(DataLoggerFileColumns).all() + + def DataLoggerFiles(self): + """ + * Pass nothing - return a list of all objects + + """ + return self._session.query(DataLoggerFiles).all() + + def DataloggerProgramFiles(self): + """ + * Pass Nothing - return a list of all objects + + """ + return self._session.query(DataLoggerProgramFiles).all() + + def EquipmentModels(self): + """ + * Pass Nothing - return a list of all objects + + """ + return self._session.query(EquipmentModels).all() + + def EquipmentUsed(self): + """ + * Pass Nothing - return a list of all objects + + """ + return self._session.query(EquipmentUsed).all() + + def InstrumentOutputVariables(self, modelid=None, variableid=None): + """ + * Pass Nothing - return a list of all objects + * Pass ModelID + * Pass VariableID + + """ + i = self._session.query(InstrumentOutputVariables) + if modelid: + i = i.filter_by(ModelID=modelid) + if variableid: + i = i.filter_by(VariableID=variableid) + return i.all() + + def RelatedEquipment(self, code=None): + """ + * Pass nothing - return a list of all objects + * Pass code- return a single object with the given code + + """ + r = self._session.query(RelatedEquipment) + if code: + r = r.filter_by(EquipmentCode=code) + return r.all() + + # Extension Properties + def getExtensionProperties(self, exptype=None, **kwargs): + """ + * Pass nothing - return a list of all objects + * Pass type- return a list of all objects of the given type + + """ + # Todo what values to use for extensionproperties type + self._check_kwargs(['type'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the exptype parameter instead.', + DeprecationWarning, stacklevel=2) + exptype = kwargs['type'] + e = ExtensionProperties + if exptype == 'action': + e = ActionExtensionPropertyValues + elif exptype == 'citation': + e = CitationExtensionPropertyValues + elif exptype == 'method': + e = MethodExtensionPropertyValues + elif exptype == 'result': + e = ResultExtensionPropertyValues + elif exptype == 'samplingfeature': + e = SamplingFeatureExtensionPropertyValues + elif exptype == 'variable': + e = VariableExtensionPropertyValues + try: + return self._session.query(e).all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # External Identifiers + def getExternalIdentifiers(self, eitype=None, **kwargs): + """ + * Pass nothing - return a list of all objects + * Pass type- return a list of all objects of the given type + + """ + self._check_kwargs(['type'], kwargs) + if 'type' in kwargs: + warnings.warn('The parameter \'type\' is deprecated. Please use the eitype parameter instead.', + DeprecationWarning, stacklevel=2) + eitype = kwargs['type'] + e = ExternalIdentifierSystems + if eitype.lowercase == 'citation': + e = CitationExternalIdentifiers + elif eitype == 'method': + e = MethodExternalIdentifiers + elif eitype == 'person': + e = PersonExternalIdentifiers + elif eitype == 'referencematerial': + e = ReferenceMaterialExternalIdentifiers + elif eitype == 'samplingfeature': + e = SamplingFeatureExternalIdentifiers + elif eitype == 'spatialreference': + e = SpatialReferenceExternalIdentifiers + elif eitype == 'taxonomicclassifier': + e = TaxonomicClassifierExternalIdentifiers + elif eitype == 'variable': + e = VariableExternalIdentifiers + try: + return self._session.query(e).all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # TODO functions for Lab Analyses + # Lab Analyses + def getDirectives(self): + """ + getDirectives(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(Directives).all() + + def getActionDirectives(self): + """ + getActionDirectives(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(ActionDirectives).all() + + def getSpecimenBatchPositions(self): + """ + getSpecimenBatchPositions(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(SpecimenBatchPositions).all() + + # TODO functions for Provenance + # Provenance + def getAuthorLists(self): + """ + getAuthorLists(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(AuthorLists).all() + + def getDatasetCitations(self): + """ + getDatasetCitations(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(DataSetCitations).all() + + def getDerivationEquations(self): + """ + getDerivationEquations(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(DerivationEquations).all() + + def getMethodCitations(self): + """ + getMethodCitations(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(MethodCitations).all() + + def getRelatedAnnotations(self): + """ + getRelatedAnnotations(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(RelatedAnnotations).all() + + def getRelatedCitations(self): + """ + getRelatedCitations(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(RelatedCitations).all() + + def getRelatedDatasets(self): + """ + getRelatedDatasets(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(RelatedDataSets).all() + + def getRelatedResults(self): + """ + getRelatedResults(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(RelatedResults).all() + + def getResultDerivationEquations(self): + """ + getResultDerivationEquations(self) + * Pass nothing - return a list of all objects + + """ + return self._session.query(ResultDerivationEquations).all() + + def getResultValues(self, resultids, starttime=None, endtime=None, lowercols=True): + """ + Retrieve result values associated with the given result. + + **The resultids must be associated with the same result type** + Args: + resultids (list): List of SamplingFeatureIDs. + starttime (object, optional): Start time to filter by as datetime object. + endtime (object, optional): End time to filter by as datetime object. + lowercols (bool, optional): Make column names to be lowercase. + Default to True. + **Please start upgrading your code to rely on CamelCase column names, + In a near-future release, + the default will be changed to False, + and later the parameter may be removed**. + + Returns: + DataFrame: Pandas dataframe of result values. + + Examples: + >>> READ = ReadODM2(SESSION_FACTORY) + >>> READ.getResultValues(resultids=[10, 11]) + >>> READ.getResultValues(resultids=[100, 20, 34], starttime=datetime.today()) + >>> READ.getResultValues(resultids=[1, 2, 3, 4], + >>> starttime=datetime(2000, 01, 01), + >>> endtime=datetime(2003, 02, 01), lowercols=False) + + """ + restype = self._session.query(Results).filter_by(ResultID=resultids[0]).first().ResultTypeCV + ResultValues = TimeSeriesResultValues + if 'categorical' in restype.lower(): + ResultValues = CategoricalResultValues + elif 'measurement' in restype.lower(): + ResultValues = MeasurementResultValues + elif 'point' in restype.lower(): + ResultValues = PointCoverageResultValues + elif 'profile' in restype.lower(): + ResultValues = ProfileResultValues + elif 'section' in restype.lower(): + ResultValues = SectionResults + elif 'spectra' in restype.lower(): + ResultValues = SpectraResultValues + elif 'time' in restype.lower(): + ResultValues = TimeSeriesResultValues + elif 'trajectory' in restype.lower(): + ResultValues = TrajectoryResultValues + elif 'transect' in restype.lower(): + ResultValues = TransectResultValues + + q = self._session.query(ResultValues).filter(ResultValues.ResultID.in_(resultids)) + if starttime: + q = q.filter(ResultValues.ValueDateTime >= starttime) + if endtime: + q = q.filter(ResultValues.ValueDateTime <= endtime) + try: + # F841 local variable 'vals' is assigned to but never used + # vals = q.order_by(ResultType.ValueDateTime) + query = q.statement.compile(dialect=self._session_factory.engine.dialect) + df = pd.read_sql_query( + sql=query, + con=self._session_factory.engine, + params=query.params + ) + if not lowercols: + df.columns = [self._get_columns(ResultValues)[c] for c in df.columns] + else: + warnings.warn( + 'In a near-future release, ' + 'the parameter \'lowercols\' default will be changed to False, ' + 'and later the parameter may be removed.', + DeprecationWarning, stacklevel=2) + return df + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # SamplingFeatures + # Site + def getSpatialReferences(self, srsCodes=None): + """ + getSpatialReferences(self, srsCodes=None) + * Pass nothing - return a list of all Spatial References + * Pass in a list of SRS Codes- + + """ + q = self._session.query(SpatialReferences) + if srsCodes: + q.filter(SpatialReferences.SRSCode.in_(srsCodes)) + try: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Simulation + def getSimulations(self, name=None, actionid=None): + """ + getSimulations(self, name=None, actionid=None) + * Pass nothing - get a list of all converter simuation objects + * Pass a SimulationName - get a single simulation object + * Pass an ActionID - get a single simulation object + + """ + s = self._session.query(Simulations) + if name: + s = s.filter(Simulations.SimulationName.ilike(name)) + if actionid: + s = s.filter_by(ActionID=actionid) + try: + return s.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + def getModels(self, codes=None): + """ + getModels(self, codes=None) + * Pass nothing - return a list of all Model Objects + * Pass a list of ModelCodes - get a list of converter objects related to the converter having ModeCode + + """ + m = self._session.query(Models) + if codes: + m = m.filter(Models.ModelCode.in_(codes)) + try: + return m.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + def getRelatedModels(self, modid=None, code=None, **kwargs): + """ + getRelatedModels(self, id=None, code=None) + * Pass a ModelID - get a list of converter objects related to the converter having ModelID + * Pass a ModelCode - get a list of converter objects related to the converter having ModeCode + + """ + self._check_kwargs(['id'], kwargs) + if 'id' in kwargs: + warnings.warn('The parameter \'id\' is deprecated. Please use the modid parameter instead.', + DeprecationWarning, stacklevel=2) + modid = kwargs['id'] + m = self._session.query(Models).select_from(RelatedModels).join(RelatedModels.ModelObj) + if modid: + m = m.filter(RelatedModels.ModelID == modid) + if code: + m = m.filter(Models.ModelCode == code) + + try: + return m.all() + except Exception as e: + print('Error running Query: {}'.format(e)) + return None diff --git a/odm2api/services/updateService.py b/odm2api/services/updateService.py new file mode 100644 index 0000000..e7a46e4 --- /dev/null +++ b/odm2api/services/updateService.py @@ -0,0 +1,93 @@ +from __future__ import (absolute_import, division, print_function) + +__author__ = 'jmeline' + +from datetime import datetime + +from odm2api import serviceBase +from odm2api.models import (Actions, Results) + + +# ################################################################################ +# Annotations +# ################################################################################ + +class UpdateODM2(serviceBase): + def update(self, value): + self._session.add(value) + self._session.commit() + return value + + # ################################################################################ + # Core + # ################################################################################ + def updateResultValidDateTime(self, resultId, dateTime): + + # check type of "validdatetime' + # if not datetime do this: + # dt = dateTime.to_datetime() + # else dt = dateTime + if (type(dateTime) != datetime): + dt = dateTime.to_datetime() + else: + dt = dateTime + q = self._session.query(Results).filter(Results.ResultID == int(resultId)) + q.update({'ValidDateTime': dt}) + + self._session.commit() + + def updateResult(self, resultID=None, valuecount=None, result=None): + if resultID: + q = self._session.query(Results).filter(Results.ResultID == int(resultID)) + if valuecount: + q.update({'ValueCount': valuecount}) + if result: + self._session.add(result) + self._session.commit() + + def updateAction(self, actionID=None, begin=None, end=None, action=None): + if actionID: + q = self._session.query(Actions).filter(Actions.ActionID == int(actionID)) + # if (type(begin) != datetime): + # begin = begin.to_datetime() + # if (type(end) != datetime): + # end = end.to_datetime() + + if begin: + q.update({'BeginDateTime': begin}) + if end: + q.update({'EndDateTime': end}) + elif action: + self._session.add(action) + self._session.commit() + +# ################################################################################ +# Data Quality +# ################################################################################ +# ################################################################################ +# Equipment +# ################################################################################ +# ################################################################################ +# Extension Properties +# ################################################################################ +# ################################################################################ +# External Identifiers +# ################################################################################ +# ################################################################################ +# Lab Analyses +# ################################################################################ +# ################################################################################ +# Provenance +# ################################################################################ +# ################################################################################ +# Results +# ################################################################################ +# ################################################################################ +# Sampling Features +# ################################################################################ +# ################################################################################ +# Sensors +# ################################################################################ +################################################################################ +# ODM2 +# ################################################################################ diff --git a/requirements-dev.txt b/requirements-dev.txt index 2287a7a..fec3a4d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -4,7 +4,6 @@ flake8-builtins flake8-comprehensions flake8-import-order flake8-mutable -flake8-print flake8-quotes mock nbsphinx