diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..113ab62 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +odm2api/_version.py export-subst diff --git a/.gitignore b/.gitignore index 7100c6d..93e9b47 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ *.py[cod] *~ -.ipynb_checkpoints + # C extensions *.so @@ -40,6 +40,9 @@ nosetests.xml log *.log -.idea + .DS_Store +.ipynb_checkpoints +.cache +.idea diff --git a/.travis.yml b/.travis.yml index abd6ac2..90deaea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: python + sudo: required + # if the https://travis-ci.org/ODM2/ODM2PythonAPI/requests ever says: missing config # validate at: http://lint.travis-ci.org/ python: @@ -14,52 +16,89 @@ python: # command to install dependencies cache: directories: - - $HOME/.cache/pip/wheels - - $HOME/virtualenv/python2.7.9 + - $HOME/miniconda + +env: + global: + - secure: "ckOXS/SsEQGGI6XrdJbEhImPbMyB8HBIqGWJ7CkYKezKTTyuJ510LMAK/7xFLyMQ0rXIrHVpCZsGLsAuzK+h2D0/xQTvkLlxJkTkKwKnm6HKg6fOrbEVSAOzCKYAdP+nBpNLGA/kzMW26E+MSWuFQwc7JiKj36vW9uUgRiT8Knwl9YrfRG+Et1bWJIfbfNoBy2gP3eFXyLBKOcgR0E0y2dyst/uRwkkEn9m8as+PWc3zsVaFS6qf5L4OFMLI5z/EZiNXiu5B/AUvpesWT/OXsbpwnxShska3RXZIh+0exu8euop7Oi4o07PI7EasMtncWzjWKLB6hJaz/BRfS/fjH0/Isy64OUXCIaCwQew31e2uW/liYnlNY/PDJfiVYdbMR34YLLrstCdBjHG+l29eN0VrCKrhW9RDPVW5eKZD1EsQPUgEDpYHaigJBwuAguQ0/MMaZ7Z/DVOR4yUsNlKFO7VwdUL4+lQ3mHrdUAEhuZACncZJ03wouvtyiuGC2WPnPAvk97uHwUcJl7Mq/jTy7HrnTRytHVIHZ8LsymAaGL2ukjVLlJ8ex8/36v2glQEkPAT06f9JXkbWJRzutnDiFKli96shMM17qyl2rjjFdC+fVDm7L7xsgJDAgXAuhD9Wwj3iVo/fcz7SmcH+iEekRtgqwbzaT3MbmLRpS4tOarY=" + +# Removing the directory will remove the env but leave the cached packages +# at $HOME/miniconda/pkgs. That is a win-win because when re-creating the +# env we will download only the new packages. +before_cache: + - rm -rf $HOME/miniconda/envs/TEST + services: - mysql - postgresql + addons: + postgresql: "9.5" apt: packages: - - cmake - - unixodbc - - unixodbc-dev - - odbcinst1debian2 - - odbcinst - - freetds-dev - - freetds-bin - - tdsodbc - - libc6 - - e2fsprogs - - mysql-client - - libproj-dev - - libgeos-dev - - libspatialite-dev -# mariadb: '10.1' -before_script: - - ./scripts/mysql_setup.sh - - ./scripts/postgres_setup.sh - - ./scripts/freetds.sh + - postgresql-9.5-postgis-2.3 + - mysql-server-5.6 + +matrix: + fast_finish: true + include: + - python: 2.7 + env: TEST_TARGET=default + - python: 3.6 + env: TEST_TARGET=default + - python: 2.7 + env: TEST_TARGET=coding_standards + - python: 3.6 + env: TEST_TARGET=docs + allow_failures: + - python: 2.7 + env: TEST_TARGET=coding_standards + - python: 3.6 + env: TEST_TARGET=default before_install: -# python -m pip makes the install go into the virtualenv - - python -m pip install pandas - - export PYMSSQL_BUILD_WITH_BUNDLED_FREETDS=1;python -m pip install pymssql - - python -m pip install mysql-python -install: # now just our code - - pip install git+https://github.com/ODM2/geoalchemy.git@odm2#egg=geoalchemy-0.7.3 - - pip install . - - pip install -r requirements_tests.txt --allow-external pyodbc --allow-unverified pyodbc - # pysqlite - - pip install pysqlite - - pip list + - ./ci-helpers/mysql_setup.sh + - ./ci-helpers/postgres_setup.sh + - | + URL="http://bit.ly/miniconda" + echo "" + if [ ! -f $HOME/miniconda/bin/conda ] ; then + echo "Fresh miniconda installation." + wget $URL -O miniconda.sh + rm -rf $HOME/miniconda + bash miniconda.sh -b -p $HOME/miniconda + fi + - export PATH="$HOME/miniconda/bin:$PATH" + - conda config --set always_yes yes --set changeps1 no --set show_channel_urls true + - conda update conda + - conda config --add channels conda-forge --force + - conda config --add channels odm2 --force + - conda create --name TEST python=$TRAVIS_PYTHON_VERSION --file requirements.txt --file requirements-dev.txt + - source activate TEST -# don't forget to open up the azure mssql server to these addreses -# https://docs.travis-ci.com/user/ip-addresses/ +install: + - python setup.py sdist && version=$(python setup.py --version) && pushd dist && pip install odm2api-${version}.tar.gz && popd -# command to run tests script: + - if [[ $TEST_TARGET == 'default' ]]; then + cp -r tests /tmp && cd /tmp ; + py.test -vv tests ; + fi + + - if [[ $TEST_TARGET == 'coding_standards' ]]; then + find . -type f -name "*.py" ! -name 'conf.py' ! -name '_version.py' ! -name 'versioneer.py' | xargs flake8 --max-line-length=110 ; + fi - - py.test + - if [[ $TEST_TARGET == 'docs' ]]; then + set -e ; + conda install doctr ; + pushd docs ; + make clean html linkcheck ; + popd ; + python -m doctr deploy --sync .; + python -m doctr deploy --sync --no-require-master --built-docs docs/build/html "docs-$TRAVIS_BRANCH" ; + fi +doctr: + require-master: true + sync: False diff --git a/Examples/APIDemo.ipynb b/Examples/APIDemo.ipynb index b4f6182..c2f5518 100644 --- a/Examples/APIDemo.ipynb +++ b/Examples/APIDemo.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 30, "metadata": { "collapsed": false }, @@ -15,7 +15,8 @@ "\n", "import matplotlib.pyplot as plt\n", "from matplotlib import dates\n", - "%matplotlib inline\n", + "%matplotlib notebook\n", + "# inline\n", "\n", "from odm2api.ODMconnection import dbconnection\n", "from odm2api.ODM2.services.readService import *\n", @@ -28,12 +29,12 @@ "session_factory = dbconnection.createConnection('mysql', 'localhost', 'ODM2', 'ODM', 'odm')#mysql\n", "#session_factory = dbconnection.createConnection('connection type: sqlite|mysql|mssql|postgresql', '/your/path/to/db/goes/here', 2.0)#sqlite\n", "# session_factory= dbconnection.createConnection('mssql', \"(local)\", \"LBRODM2\", \"ODM\", \"odm\")#win MSSQL\n", - "# session_factory= dbconnection.createConnection('mssql', \"odm2\", \"\", \"ODM\", \"odm\")#mac/linux MSSQL\n" + "# session_factory= dbconnection.createConnection('mssql', \"odm2\", \"\", \"ODM\", \"odm\")#mac/linux MSSQL" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 31, "metadata": { "collapsed": false }, @@ -41,90 +42,16 @@ "source": [ "_session = session_factory.getSession()\n", "\n", - "read = ReadODM2(session_factory)\n" + "read = ReadODM2(session_factory)" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [], - "source": [ - "# dir (read)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "USU3: Battery voltage\n", - "USU4: Turbidity\n", - "USU5: Turbidity\n", - "USU6: Turbidity\n", - "USU7: Turbidity\n", - "USU8: Turbidity\n", - "USU9: Turbidity\n", - "USU10: Temperature\n", - "USU13: Gage height\n", - "USU14: Temperature\n", - "USU15: Relative humidity\n", - "USU16: Precipitation\n", - "USU17: Battery voltage\n", - "USU18: Wind speed\n", - "USU19: Wind direction\n", - "USU20: Wind direction\n", - "USU21: Barometric pressure\n", - "USU22: Radiation, incoming shortwave\n", - "USU23: Battery voltage\n", - "USU24: Wind speed\n", - "USU25: Temperature\n", - "USU26: Temperature\n", - "USU27: Temperature\n", - "USU28: Relative humidity\n", - "USU29: Barometric pressure\n", - "USU30: Precipitation\n", - "USU31: Radiation, incoming shortwave\n", - "USU32: Oxygen, dissolved\n", - "USU33: Oxygen, dissolved percent of saturation\n", - "USU34: Specific conductance\n", - "USU35: pH\n", - "USU36: Temperature\n", - "USU37: Turbidity\n", - "USU39: Phosphorus, total\n", - "USU40: Phosphorus, total dissolved\n", - "USU41: Solids, total Suspended\n", - "USU44: Discharge\n", - "USU47: Solids, total suspended\n", - "USU48: Phosphorus, total\n", - "USU49: Distance\n", - "USU50: Snow Depth\n", - "USU51: Distance\n", - "USU52: Distance\n", - "USU53: Distance\n", - "USU54: Snow Depth\n", - "USU55: Snow Depth\n", - "USU56: Snow Depth\n", - "USU57: Volumetric water content\n", - "USU58: Electrical conductivity\n", - "USU59: Temperature\n", - "USU60: Temperature\n", - "USU61: Real dielectric constant\n", - "USU62: Imaginary dielectric constant\n", - "USU63: Alkalinity, carbonate plus bicarbonate\n", - "USU64: Nitrogen, total dissolved\n", - "USU65: Nitrogen, total\n" - ] - } - ], "source": [ "# Run some basic sample queries.\n", "# ------------------------------\n", @@ -132,12 +59,12 @@ "allVars = read.getVariables()\n", "\n", "for x in allVars:\n", - " print x.VariableCode + \": \" + x.VariableNameCV\n" + " print x.VariableCode + \": \" + x.VariableNameCV" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "metadata": { "collapsed": false }, @@ -146,21 +73,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "Jeff Horsburgh\n", - "Nancy Mesner\n", - "Amber Spackman\n", - "\n", - "-------- Information about an Affiliation ---------\n", - "Jeff: 1\n", - "Jeff: 2\n", - "Amber: 3\n", - "Nancy: 4\n", - "Amber: 6\n" + "Jeff Horsburgh\nNancy Mesner\nAmber Spackman\nErin Jones\nJanet Barnette\nJason Bahr\nChris Cox\nUnknown Person\nLisa Ward\n\n-------- Information about an Affiliation ---------\nJeff: 1\nJeff: 2\nAmber: 3\nNancy: 4\nAmber: 6\nJeff: 6\nErin: 46\nJanet: 48\nJason: 45\nChris: 45\nUnknown: 45\nLisa: 47\n" ] } ], "source": [ - "\n", "# Get all of the people from the database\n", "allPeople = read.getPeople()\n", "\n", @@ -169,47 +86,25 @@ "\n", "try:\n", " print \"\\n-------- Information about an Affiliation ---------\"\n", - " allaff = read.getAllAffiliations()\n", + " allaff = read.getAffiliations()\n", " for x in allaff:\n", " print x.PersonObj.PersonFirstName + \": \" + str(x.OrganizationID)\n", "except Exception as e:\n", - " print \"Unable to demo getAllAffiliations\", e\n", - "\n" + " print \"Unable to demo getAllAffiliations\", e" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 33, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "-------- Information about an SamplingFeature of type 'Site'---------\n", - "USU-LBR-Mendon: Little Bear River at Mendon Road near Mendon, Utah\n", - "USU-LBR-SFWeather: Little Bear River South Fork Weather Station near Avon, Utah\n", - "\n", - "-------- Information about an individual SamplingFeature ---------\n", - "The following are some of the attributes of a SamplingFeature retrieved using getSamplingFeatureByCode(): \n", - "\n", - "SamplingFeatureCode: USU-LBR-Mendon\n", - "SamplingFeatureName: Little Bear River at Mendon Road near Mendon, Utah\n", - "SamplingFeatureDescription: Located below county road bridge at Mendon Road crossing\n", - "SamplingFeatureGeotypeCV: Point\n", - "SamplingFeatureGeometry: \u0000\u0000\u0000\u0000\u0001\u0001\u0000\u0000\u0000ž·±Ù‘ü[ÀŽ\u0007[ìöÛD@\n", - "Elevation_m: 1345.0\n" - ] - } - ], + "outputs": [], "source": [ "# Get all of the SamplingFeatures from the database that are Sites\n", "\n", "try:\n", - " siteFeatures = read.getSamplingFeaturesByType('Site')\n", + " siteFeatures = read.getSamplingFeatures(type='Site')\n", " numSites = len(siteFeatures)\n", " print \"\\n-------- Information about an SamplingFeature of type 'Site'---------\"\n", " for x in siteFeatures:\n", @@ -220,7 +115,7 @@ "\n", "# Now get the SamplingFeature object for a SamplingFeature code\n", "try:\n", - " sf = read.getSamplingFeatureByCode('USU-LBR-Mendon')\n", + " sf = read.getSamplingFeatures(codes= ['USU-LBR-Mendon'])[0]\n", " \n", " print \"\\n-------- Information about an individual SamplingFeature ---------\"\n", " print \"The following are some of the attributes of a SamplingFeature retrieved using getSamplingFeatureByCode(): \\n\"\n", @@ -231,29 +126,16 @@ " print \"SamplingFeatureGeometry: %s\" % sf.FeatureGeometry\n", " print \"Elevation_m: %s\" % str(sf.Elevation_m)\n", "except Exception as e:\n", - " print \"Unable to demo getSamplingFeatureByCode: \", e\n", - "\n", - "\n", - "\n" + " print \"Unable to demo getSamplingFeatureByCode: \", e" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 14, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "------------ Create Sampling Feature --------- \n", - "new sampling feature added to database error adding a sampling feature: 'str' object has no attribute 'geom_wkb'\n" - ] - } - ], + "outputs": [], "source": [ "#add sampling feature\n", "print \"\\n------------ Create Sampling Feature --------- \\n\",\n", @@ -279,41 +161,17 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 34, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "------------ Foreign Key Example --------- \n", - "The FeatureAction object for the Result is: \n", - "The Action object for the Result is: \n", - "\n", - "The following are some of the attributes for the Action that created the Result: \n", - "ActionTypeCV: Observation\n", - "ActionDescription: Sensor deployment and \r\n", - "\tobservation. This is a generic Observation Action created for a Time Series \r\n", - "\tResult loaded into ODM2\tfrom an ODM 1.1.1 database.\n", - "BeginDateTime: 2007-09-01 00:00:00\n", - "EndDateTime: 2007-09-30 23:30:00\n", - "MethodName: Battery voltage measured by Campbell Scientific CR206 datalogger.\n", - "MethodDescription: Battery voltage measured by Campbell Scientific CR206 datalogger.\n" - ] - } - ], + "outputs": [], "source": [ - "\n", "# Drill down and get objects linked by foreign keys\n", "print \"\\n------------ Foreign Key Example --------- \\n\",\n", "try:\n", " # Call getResults, but return only the first result\n", - " firstResult = read.getResults()[0]\n", + " firstResult = read.getResult()[0]\n", " print \"The FeatureAction object for the Result is: \", firstResult.FeatureActionObj\n", " print \"The Action object for the Result is: \", firstResult.FeatureActionObj.ActionObj\n", " print (\"\\nThe following are some of the attributes for the Action that created the Result: \\n\" +\n", @@ -324,15 +182,12 @@ " \"MethodName: \" + firstResult.FeatureActionObj.ActionObj.MethodObj.MethodName + \"\\n\" +\n", " \"MethodDescription: \" + firstResult.FeatureActionObj.ActionObj.MethodObj.MethodDescription)\n", "except Exception as e:\n", - " print \"Unable to demo Foreign Key Example: \", e\n", - "\n", - "\n", - "\n" + " print \"Unable to demo Foreign Key Example: \", e" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 28, "metadata": { "collapsed": false }, @@ -341,16 +196,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "\n", - "------- Example of Retrieving Attributes of a Time Series Result -------\n", - "The following are some of the attributes for the TimeSeriesResult retrieved using getTimeSeriesResultByResultID(): \n", - "ResultTypeCV: Time series coverage\n", - "ProcessingLevel: Raw data\n", - "SampledMedium: Not applicable\n", - "Variable: USU3: Battery voltage\n", - "AggregationStatistic: Minimum\n", - "Elevation_m: 1345.0\n", - "SamplingFeature: USU-LBR-Mendon - Little Bear River at Mendon Road near Mendon, Utah\n" + "\n------- Example of Retrieving Attributes of a Time Series Result -------\nThe following are some of the attributes for the TimeSeriesResult retrieved using getTimeSeriesResultByResultID(): \nResultTypeCV: Time series coverage\nProcessingLevel: Raw data\nSampledMedium: Not applicable\nVariable: USU3: Battery voltage\nAggregationStatistic: Minimum\nElevation_m: 1345.0\nSamplingFeature: USU-LBR-Mendon - Little Bear River at Mendon Road near Mendon, Utah\n" ] } ], @@ -358,77 +204,38 @@ "# Now get a particular Result using a ResultID\n", "print \"\\n------- Example of Retrieving Attributes of a Time Series Result -------\"\n", "try:\n", - " tsResult = read.getTimeSeriesResultByResultId(1)\n", + " #tsResult = read.getTimeSeriesResultByResultId(1)\n", + " tsResult = read.getResults(ids = [1])[0]\n", " print (\n", " \"The following are some of the attributes for the TimeSeriesResult retrieved using getTimeSeriesResultByResultID(): \\n\" +\n", - " \"ResultTypeCV: \" + tsResult.ResultObj.ResultTypeCV + \"\\n\" +\n", + " \"ResultTypeCV: \" + tsResult.ResultTypeCV + \"\\n\" +\n", " # Get the ProcessingLevel from the TimeSeriesResult's ProcessingLevel object\n", - " \"ProcessingLevel: \" + tsResult.ResultObj.ProcessingLevelObj.Definition + \"\\n\" +\n", - " \"SampledMedium: \" + tsResult.ResultObj.SampledMediumCV + \"\\n\" +\n", + " \"ProcessingLevel: \" + tsResult.ProcessingLevelObj.Definition + \"\\n\" +\n", + " \"SampledMedium: \" + tsResult.SampledMediumCV + \"\\n\" +\n", " # Get the variable information from the TimeSeriesResult's Variable object\n", - " \"Variable: \" + tsResult.ResultObj.VariableObj.VariableCode + \": \" + tsResult.ResultObj.VariableObj.VariableNameCV + \"\\n\"\n", + " \"Variable: \" + tsResult.VariableObj.VariableCode + \": \" + tsResult.VariableObj.VariableNameCV + \"\\n\"\n", " \"AggregationStatistic: \" + tsResult.AggregationStatisticCV + \"\\n\" +\n", " \"Elevation_m: \" + str(sf.Elevation_m) + \"\\n\" +\n", " # Get the site information by drilling down\n", - " \"SamplingFeature: \" + tsResult.ResultObj.FeatureActionObj.SamplingFeatureObj.SamplingFeatureCode + \" - \" +\n", - " tsResult.ResultObj.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName)\n", + " \"SamplingFeature: \" + tsResult.FeatureActionObj.SamplingFeatureObj.SamplingFeatureCode + \" - \" +\n", + " tsResult.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName)\n", "except Exception as e:\n", " print \"Unable to demo Example of retrieving Attributes of a time Series Result: \", e" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 27, "metadata": { "collapsed": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "-------- Example of Retrieving Time Series Result Values ---------\n", - " \n", - " ValueID ResultID DataValue ValueDateTime ValueDateTimeUTCOffset \\\n", - "0 1947519 1 11.71689 2007-09-30 04:30:00 -7 \n", - "1 1948350 1 11.73368 2007-09-30 02:30:00 -7 \n", - "2 1952427 1 11.79663 2007-09-29 22:30:00 -7 \n", - "3 1955496 1 11.83189 2007-09-29 19:00:00 -7 \n", - "4 1957822 1 11.86547 2007-09-29 16:30:00 -7 \n", - "\n", - " CensorCodeCV QualityCodeCV TimeAggregationInterval \\\n", - "0 Not censored Unknown 30.0 \n", - "1 Not censored Unknown 30.0 \n", - "2 Not censored Unknown 30.0 \n", - "3 Not censored Unknown 30.0 \n", - "4 Not censored Unknown 30.0 \n", - "\n", - " TimeAggregationIntervalUnitsID \n", - "0 102 \n", - "1 102 \n", - "2 102 \n", - "3 102 \n", - "4 102 \n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAb4AAAEECAYAAABX3FH6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsXWeYXVXVftfMZFJnJsmk90IaCSEJkEINvQuKSlEhoFhA\nREDBgoINlU8ERfFDRDBKEfgURUSRMlITSpCEGoRACCQhpJCQRjKzvh/rbO6+556zy51zuJOZ/T7P\nfe499667zzptv3utvdbaxMwICAgICAjoKKiqtAIBAQEBAQEfJALxBQQEBAR0KATiCwgICAjoUAjE\nFxAQEBDQoRCILyAgICCgQyEQX0BAQEBAh0IgPgOIaAkRHVBpPfIEEf2KiL7p+Z/7iei0vHSqJIjo\nGSLat9J6tFUQ0UVE9PtK69EaENFwImohotD/RYjOx6hK6+ELItqPiF73/Z/1whPRq0S0iYjWE9Fq\nIrqDiAY7KlVygxHRKUT0oK+ilUb0wM+ttB5JsBG06eZg5i8w8w/S5LI8bu1+WB+9lhPRL4moOov2\ny9j/K0R0gS7DzJOY+YEPQh8TiOg6IvquRaaFiFbEnq8aInqLiJpzVC/z5N+oX9geXZd1RPQUER2Z\n9X40tMkEZiK6OLquZ8W+Pzv6/ts57Tr385HWD+kD6TL7G2/dXUY8DOBIZq4HMBDAWwCudGyfov9T\nwndl4YPqJNshXM55q66Nhx4N0f20C4BZAM7MeieG+0Tf/8cAfIuIDsx6/466ZIG1AA7Xtg8HsCbH\n/eWJR5i5npl7AvgVgJuJqL7SSuWFlPuCAbwI4OTY9ydH3+emTo5t62gTAw5XU58AgJnfA3AbgJ3f\n/4HoCCJaQETvENFrRHSR9r9/R+/ropHcTMgNPYuINhDRmqiNWiL6SfT/5UR0FRF1jn7bj4heJ6Lz\niWg5gN8S0SJ9NBiNclcR0a4lihM9R0RHaNvV0Yh4SrT9oci9tYaI7iOi8QltHArgGwCOj/R+Kvp+\nTtT+eiL6LxF9Nva/84noTSJaRkSf1t0JpmNO2P8oIrqXiN6OdP+D6hCi0dEwAHdEenwlqY00KMuC\niLoB+DuAQdExrieiE5OOO6GN06LzsJqI7iKiYbbdAgAzvw3gXyi+nwYS0W3Rcb6sj3yJaA8ieoSI\n1hLRG0R0JRHVaL+3ENEZRLQYwGKH/T8J4FkAU7Q2lhDRAZEem4iop/bb1Og+q7Ydt4suRHRLdO3X\nElETEU2Ivj8dwCcAnB9dh78YjuX3AE7Rtk8G8LvYfuqJ6DfRvfg6EX2PiCj67RQiepCI/id6Bl4m\nosO0/46IdHuHiP4JoE+s7dTnJzqX5xHR09Ex3kREtYZjiR9XdwBjHPd1QfQMro9kjtV+q4qetVVE\n9F8ARkvSpjcRHUVika4looeIaBdHPU6J5H9KRG8DuAjJeAJAN+1+2BlAFwCPx/Q06WE7hq9SoW86\nFRohRffL3OgZXELaVIjtfmkNqMx+VkToXCJaSdIvzLHujJmNLwBLABwQfe4G4HoA12m/7wtgYvR5\nEoDlAD4UbQ8H0AyANPlTADwQ28flAG4H0AC52f8C4AfRb/sB2AbgEgCdAHQG8BUAN2v/PwbA0yn6\nXwjgD9r2kQCejT6PBfAugAMAVAP4KoCXANQkHPtFAObG2j4cwIjo8z4ANgKYEm0fBuBNAOMhN+3v\no3MxynbMCccwGsCBAGoANAJoAvDT2DXa33AN9wOwNOW36wB8N00u5bjvB3Cadu4XR+eyCnLjPpyy\nL3U/VEfbgwD8B8Ap0TZBHvpvRtdjBID/Ajg4+n0agOmR3DAIaX1Ja78FwD+jc9rZYf8zo+t/TMr9\nfg+AT2u/XQrgKpfjtukSycyBPFOdAPwUwFNJ18VwXZshg4YVAOoB9IQ8fzsDaNbk/gzgqug+7ANg\nHoDTtedxK4DTovP6eQBvaP99BMD/RDruA2C9uh/g9vzMA9A/0u05AJ9NOZb3+4WorTMBbAHQx3Ff\nxwHoH33+WCSrtj8f7XtQpMd90bmrMvR5iXoDmApgJYDdo/P1qUi+k4Mep0D6sjOieybpHr0IwFwA\nXwPwo+i7HwO4ANKHfNtRD9MxHBbdJxMAdAVwA4r7prmQe6Yb5Jl5EcCpLveL5X5N7IdQ3J/49rOK\nHy6K7ovDo98bjLo4KLsEcrOvAfAegGWIiC5F/nIAl8U6mirt9yTiexfASG17FoBXtAPboi5o9N1A\nAO8A6BFt3wrgKyn6jI707xJt/wHAhdHnC1FMoBQd374JnWDJBUnY158BnBV9vhYakUV6tGg3V+ox\nO1yTYwA8GbtGB/jecNFvrSW+v6uHItquim68oQn7Gh6dgzUQF10zgIe06zgdwKux/3wNwLUpup8N\n4P+07RYA+xnOg77/TdH+L02439U1/zSAe7XflgLYy+W4bbok6NYz+k9d/LoY/tMMYBSAXwP4LIDP\nAbg6uteaI5n+kOens/a/EwDcpz2Pi7XfukZ69AMwFPLMd9V+vwEF4nN5fk7Ufv8xooFDwrEoUlD9\nzEYAH9V+N+4rob2nABwdfb4XGuECOBh24kvUGzKA+E5M/gUA+zjocUr8/k6QV8Q3FMCrkMHuawAG\no5j4jHpYjuFaAJdov42Jrvmo6D7eCmCc9vtnLfdLM4B+Dvd4WcSXIK/3s/tF94rOMSsBTDe14erq\nPIaZe0OsrbMAPEBE/QCAiGZEboe3iGgd5OHrY2irCETUFzKyeDIyndcAuAti2SisYuZtaoOZlwN4\nGMBxRNQAYfkbktpn5pcho52jiagrgA9psoMgN5WSZQCvQ24yF90PJ6JHSVxdaq5FHfugqC2F17X/\nuRyzvp9+katiWXSO/wCPc5wzhgP4mXYcqyFuk7RzyAAambkX5Bw8AuBura3Bqq3onH4d0gmDiMaQ\nBFctj87DD1B6HpZZ9GXIee4O4DwAs0lzl8bwfwBmElF/ItoPQiYPexx3qi6R++1HketmHaSj4oTj\nMUHNy/we4uL8FKTT1DEMYq0t187p/8b2s0J9YObN0ccekHt4rfYdoD0vcHt+VmqfN0XtpuHRqJ/p\nCeCvEG+S076I6GTN7bcWwESkP4v6MaQhTe/hAM6L3aNDon3Y9EBMj1Qw8+sAXoZ4uhYz8xsxEaMe\nlmMwnY8+ELJdGvtdv6bx+4Vgvq4K2yH3YhydIIOeRFj6WQBYzcwt2rbtPvOe42Nm/jOE4feOfrsB\n4rIbzDIpfTUKDyQntBX/7u1I0YnM3Dt69WTmBsN/AHnAPwVxJzwSkWEabgZwEsRSepaZl0Tfvwm5\ngXQMRXKHVaRD5C+/DeL+6ht15HehcOzLITeigj7v5XLMOi6BjMgmRuf4k9p+SnRrBVyuVxyvA/ic\ndhy9mLkHM88z/EfdT1shrvMZRNQ7auuVWFsNzHx09L9fAXgewOjoPHwTKJmUdzkXFN3LV0BGt2ck\nCTHzOggpnwDgRMh9pLDU4bhNupwE4GiIddkT4tYlmJ+dRDDzgxAvSD+NmBVeh1h8jZqePZl5skPT\nywH0igaMCvp97PP8OIOZN0GuyaeoMG+ftq83SOZWfw3gjOj4ekHc4PqzOFT7X7wdH7wO8eTEr/sf\nHfQA/J7VuQDORWzO1qaHQ7tJ50Pp9TaEhIbHfo8TbzlYCqAPSTyBjuEokK9vP1sWvPNYiOgYFHzG\ngDDrWmbeRkTTIQ+0wipIhz1a+24lgCFE1Al4f+R2DYArIksIRDSYiA6xqHI7ZM7nSygd5cZxM4BD\nAHwBwI3a97cAOJKI9icJkPkKpJN4NKGNlQBGEJE64bXR621mbiGiw6N96G2fSkTjowt9IaKLWsYx\n10FcoxtIUkm+Gvt9BcRNYQIRUWf9lXKMjVQcSRc/7jj+F8A3SCbgQUQNRPRRkx7RC5EOJwNYwcxr\nADwWHeP5RNSFJBBpIhHtHv23DsB6Zt5EEtjwBcsxp+1fx48AXEDpQRc3RToeh+J752r4HXccdRDS\nXUtE3QH8EMUP/UrYr6mOoyADOwU1uFgBIe/LiaiOBKPIIVeRmZdC5ly/Q0SdiGhvCFkr+Dw/XmDm\ntZBn5CLLvh6BWO8tAN6OLOlTIfEGup5fip6xXpD5snJxDYDPR30diKg7SYBfdwc9fPFHSJ9yq6ce\nNtwCYA4RTYj6pvdTJCLL6RYAPyCiHkQ0HMA5EK+CFSTpCPcl/RZZsfMB/DjSt5aIzoe4ttWA0bef\nLQuuxKciBt8B8D0AJzPzC9FvZwD4XvTbhZCLBeB9M/gHAB6OzPHpkInlZwGsIKK3ItGvQYIY5kVu\nn7shk9mpYOYtEFfUSAB/ssiugDyMM2P6LYZYT7+AkPSREH/8diWiNXMrpDNZTURPMPO7kDmmWyNX\n1wmQABXV9j8A/Bziv16MQmewNXq/wOOYvwNgNwDrANwRHbeOH0HC8tcQ0bkpbQyCWJmbAGwGsIli\nCavM/CKko38lamtA/Ljj54WZb4/2f3N0HAshk+dpYEhnvx4y8pwBcT+rh+4oSJTlEkjqzDWQwA1A\ngpo+Ef33ahRbYEV6WfavH/OdkHml01Pa+CtkDmQ5My/S/mc7bpsucyEj4DcAPAPpwHVcC2BidB3S\n7m/9OjzPzM+n7P9kSOfxHORYbwUwwKCb/t9PQJ6b1QC+Bc368Hx+ysHPABxORJNM+4qO+zJI57kC\n4l58SGvnGkig0dMQIo8/P3Gk6s0SCXw6gF9Ez/1iRFG1Dnp4gZm3MPN9kWekSC+THg7H8A8AV0D6\n4sWQOVAdX4L0E68AeAASHHidSVXt81DINFQajofMO/8X4hnYH5Iu9170u1c/66BPIkiMjx0TRPQt\nAGOYOZ7z0uYQWSiLIEEGLTb5gICAgB0NRLQAwIGRxd5mscMSXzQntADAJxLmNdoESHJ4/g5xgVwP\nYDszH1dRpQICAgI6OHbIWnVE9BmIm+jOtkp6ET4Hcde9hEL+TkBAQEBABbHDWnwBAQEBAQHlYIe0\n+AICAgICAspFWuJuuwERBZM2ICAgoAww8wdVvPoDRbsnPgAI7tyAgIAAP6Sn7u74CK7OgICAgIAO\nhUB8AQEBAQEdCoH4AgICAgI6FALxBQQEBAR0KATiCwgICAjoUAjEFxAQEBDQoRCILyAgICCgQyEQ\nX0BAQEBAh0IgvoCAgICADoVAfAEBbQhbtwJbtlRai4CA9o1AfAEBbQiHHAJMmVJpLQIC2jfa/bJE\nRMTt/Rh3dPztb8DGjcDxx1dak8qjsRFYswYIt2xApUFE7bZIdSC+gIqjb1/g7bdDZw8AAwcCK1aE\ncxFQebRn4guuzoCKo29fd9mmJuCUU3JTpeKora20BvnilluARYsqrUVAR0cgvoCKo08fd9lbbgHm\nzs1Pl0qjc+dKa5Avjj8eOPPMSmsR0NERiC+g4vAhvoYGd9kNG4Bvf9td/t133WV90NQEvPaam2xb\nsfiWLweam/Npe/36fNoNCHBFIL52huZm4NFHK62FH/IivieeAL73PXf5ujoJsska++8PnHaam2xb\nIb5Bg4Arrsin7Q0b8mk3IMAVgfjaGf75T2DPPSutBfDii8D48W6yjY3u7SpZl+CPXr3cZRXWrnWX\n9YGrNZkn8fXt63d8S5fmo0ew+AIqjUB87Qzbt/vJv/GGu+yppwKvv+4mO3++kJ8LVGfvQ2ZvvmmX\n7dJF3jdtctMDyK9TdiW+vOb4mCVydt069//4nDcfvP12Pu0GBLgiEF87A3kGHw8Z4t4pX389cMcd\n2euhZF3mlBQ5+nTga9a4y77zjrusD1zde4rYs4a6xj7E+tvfZq/HoEHZtxkQ4ItAfO0MvsQHAG+9\n5S7rSiI+eigy27bN/T9bt7q3u3q1e7s+58IHrkTtk9oBAOPGAUuW2OXUdWtpcW/bR9YVeRF7QIAP\nAvG1M1SVcUVXrnSXdSURHz0UQbm4aZWsC/Ep+Fh8L7/sLuuKhgZ3i0/NYbpGVC5eDCxYYJdT56vS\nifHV1ZXdf0AAEIiv3SFvi++hh/LTw4f43nvPXdbHLZpHxOGAAe6yNTXy7kPWLpaZOhc+VpyrW/Sp\np9wHDIH4AtoCAvG1M5RDOKtWucu6EkM5Fp+Lq9PH4iuHJF0tohNPdM/N8+ns1f59BiMuOvsen4/s\nwQcDO+3kJluORyIgIGuE27BC+Oxn205RZp9O1nUeLi+LT8GFzBR8CNW1s7/5ZuCee9xklRXnArV/\nnyCbvCw+13PhQ6bB4gtoCwjEVyHcfruU38oa5VhaPmHreRBfXnN85Vh8PsTgStTlWHw+ZOJDfHlY\nfD5tBosvoC0g3IYZ4tRThdBc0Lt3PjqUY2n5EJ+rpZVXVGc5ZOYTLepDfK4BKOUQX9aWWSC+gIAC\nOuRtuGgR8MIL2bd7/fXAz3/uJusbtu6KcggnD4uvnA7Ox9XpE9XpQ6iVJj6FvIgvjxQFnzYD8QW0\nBXTI23CPPYAJE/Jp27Uk1PTp8p51eHk5xLd5s/t/2orFl1cEaB7EV84cX3t1dYY5voC2gA5JfP36\n5de2axh69+7yvmVLtvsvZ0Sdh6szL4uvHOLbkSy+cvTISza4OgPaKzrkbdijh7vsnDnAL3/pLu9K\nfKqzyLo2ZFtxdR57rL8ePq7OrCNA2zvxBYsvIKCADkl8Pq6n3/0O+PWv3WSrqtzrXrYl4nMlkaoq\nf9esz/xTXq7OPNIZXHUA8p/jyyudwRWB+AJ2NHRI4uvUyU/elUx8IjXLydfKC66Wi+9582kbqKyr\nUyEPt6Hq7PMKQskrqjPL/SsEV2dAW0CHvA19LD4fjBkj7z6utVdfzVaHciw+V3IqZ624vAjKx9VZ\n6Tk+dU3ysszycnVmuX+FQHwBbQEd8jbMi/j695d3nyhJ1/XtXFFOArtrx1WOxedTYSUvi89nuSOf\nTvyJJ9zkytE5r6hO1+MrZwDlAnV/VrpYdkDHRockvnI6cBeU08FlPedSTgJ7nq7OV16xy5Rz3vKS\n9bkef/ubm1zeeuRh8eVFfL5ehoCAPNAhiS8viy/vYAoXtDVX5/Ll7nrk5erMy+JzRTlRq3nN8X34\nw25t5kV8CoH4AiqJDkl8eUWW5Z035oI8iU8NGPLKG9vRXJ2uyFsPH4vPdUUJH+R5zwUE5IGKEh8R\nXUtEK4loofbdd4noaSJ6ioj+QUSJq5kR0WFE9AIRLSaiC3z26ztC9XUftgVXp88xunZCPpVQFHw6\n5UoSX/w/WaItEZ8rfO75cuaVA/EFVBKVtviuA3Bo7LtLmXlXZp4K4E4AF8X/RERVAH4R/XcigBOJ\naLzrTvOaWPe1+MrJi3PVIc/crqyJT6G9uzp99MgruMUVeRGfgs/1CwjIGhUlPmZ+CMDa2Hd6Cnh3\nAEmP9XQALzHza8y8DcDNAI5x36+fnq6dgC/xVVdn39H6dJy+o+9yLD6fzj64OgvIeuCSJ/GVU5km\nWHwBlUSlLb5EENH3iWgpgJMAfDtBZDAAPRFgWfSdE/K2+Hwqobh2tI89Bixb5q5DHvloCj4rI/h0\nynlVbmkrxJc1mSkZn+NzRXB1BrRntEniY+YLmXkYgBsAnJV1+/fdp/aTdcsCH1ena0c7YwbwsY+5\n6+DTyfpafHlFJ+ZVq7PSxFcOQbnooUrp+QwCXBGIL6A9I6fA/sxwI4C/A7g49v0bAIZp20Oi7xIx\nZ84cjBgxAgDQs2dPAFMAzEZLC/Dgg00AgNmzZwMAmpqKt4GmqP5m8u/6tjzUTZg/H9h9d7M882xU\nVwNLljShqSl9/2obmI133jHvHwAWLJDtlha7vuUcH1ETHn4YGD7cri8ALFrUhH79zMe3dKnIb99u\n1/eFF5pQVQVs3+6mL9CEFSvsxzd5smwvX+5+PWz7V9uyVNVsNDfb5Zctk22X6/fYY3J8L71k16dT\np9mR3m7HV13tfnxCYm7ya9bIdnOze/th+4PZbmpqwvXXXw8A7/eX7RbMXNEXgBEAFmnbO2mfzwJw\nS8J/qgH8F8BwALUA/gNgQkr7rKOlhVnGncxbt7IVAPO0aXY5ZubDDhP5Bx6wy375y8wNDczf+pZb\n2wDzkCF2uQceENkNG+yy69eL7KhRbjoMHcrcqRPzSy/ZZdU5/sMf7LJf/rLIXnaZXfbqq5m7dGH+\nxCfsso8+Ku0ee6xddvVqkT3hBLssc+H4XLD33iL74ot22S98QWTnzrXLfuYzInvhhXbZBx/007ln\nT5FtbrbL9unj3u4hh4jskiVu8gGVQ9R3Vpwj8nhV1OIjohshQ8XGaE7vIgBHEtE4AM0AXgPw+Uh2\nIIBrmPkoZm4moi8CuBvirr2WmZ932adYLZKMnVdgSV7BLRs2uOuQl6uzutpNvmtXKd3mqoeP27dT\np7Yzx6fup6z0UHDRQ1XS8Z3ja262B6Qo+S1bgG7dzLIhuCVgR0NFiY+ZT0r4+roU2eUAjtK2/wFg\nnO8+W1qko3LtwAH/qE7XTrnKM53BZd28cjpwH+KrqXGTnzkTWLzYvVN2vR5Kh7yIz+d6qLZtlYDy\nImBFfL5zfNu22cmqpUVkNm+2E5/PHJ9CIL6ASqJNBrfkCUU4PsT35JP55FX5Wnx56AD4dUK+BOWz\ndI+rzq4Wn0KeFp9P222F+FxXD+nWza3gejnBLSGPL6CS6HDEpyy+DRuA8c4p78B//mOX8XXZ+ciq\n9l1l8khg97H4fIjPZxDgQ3wfhKszr3y7PInPJR2lpSVf4gsWX0Al0eGIT5ETYC+grHcWrp2LDzH4\nujp9Ok6fXLs8XJ3KVZa1xQf4E1+eJeTysvhc7ov6ennPw+JraQG6d8+e+BQC8QVUEh2O+JTF5wKX\nlQV0+Fouebg6lcy775rldNk8XZ0+gwDX8+Y6x6eQdVCJb9t5BbcMG+avA+Du6uzSxU02WHwBOxo6\nHPHFo/A2bkyX1YMWXMgyb+LzgWsEKFF+Fp+Pq9OHJPN0dfp2yD7E7hPok1fFG8Dd1dm5s1/91Lzm\nlQMCskaHJD59hNqjR7qs/iC7Wok+nZaPq9N1VO1j8QF+5JvXHJ+vHj7E56MvAPz97246KORh/bqe\ni5YWYPRoCb5yaVfB1dXpSnzlBKwE4guoJDIhPiLqRUQTiWhUtHJCm4WPq1N/OH0svqw7ONf9q3YB\nd4vPJ7oVcJdXFl+lXZ0+16McVJL4mIHBg4F169xkFfIivjwt64CALFF2Hh8RNQA4E8CJkOopqwB0\nAdCfiOYBuIqZ789EywwRt/hM8A25ztPV6eMqA9zcWapDdnVn7YhRnT76Dhwo87otLe73SNbEB7h7\nAnzm4XxdncxS5MHl3iinFmkgvoBKojXW2W2QFRL2YeZxzLw3M+/OzEMB/AjAMUT06Uy0zBA+Fp/e\nubp2RL5k5mppqITja65xk3clszwtvrYQ1elDfERi5WQdEetL7K7Wr7LKsiY+JetKfL4Wn8+8ckBA\nHijb4mPmgw2/PQnAYebhg4ePxac/nJXs4IACWV90EXD66eZ2AfcOy8cSKceirWTlFsDv+HTi69rV\n7T+VdnXmYfGpwWGnTtkTH+AflRsQkDXKtviI6DkiupCIRmepUN4o1+JzfajzmuNTZN3QYG8XcLf4\nVLuuFm2lg1vydHUC/hafj84+NVxdreouXdxdlwq23Dw1KHN1g/vmS/oMRgIC8kBrXJ0nQlZIv5uI\nHiOic4hoUEZ65QblanHp6NuSxacIqrbW3i7gF+7vOn8I+Ae3VLpIdVtxdfoEitTWuh+fckfa7mcf\n4lNznHlYfO2d+F55BfjznyutRYANZRMfMz/NzF9n5tEAvgRZH28eEd1PRAZnXGVRbnCLL/F985vm\nyEol6zrHp6xUVabK1C7g3mH5FOxuK8EteUV15k18Li5JwI/Yq6vdCEq/z7ZsMcuWQ3w+83a+88o7\nEr76VeAjH6m0FgE2ZJJ6wMzzmPkcACcD6AngF1m0mwfKdXX6dEQtLcAllwDz5rnJukCRtY34FFxd\nnXkRn086A+Cnw45q8bnOxbkSjrqXa2vdA1YAN4tPzfHlcZ7bs8XXXo+rvaHVyxIR0R4Qt+dxAJYA\nuBrAra1tNy/kHdyiP9Q2gi3H1Zm1xQf4jcDzWJ3BdxDg2yG7Ek5bIj6fpa1c2i5njs/H4uvUKRAf\nkF8lpoBs0ZrglkuI6GUAVwF4A8BezDybmf+XmVdnpmHGKNfiO/RQt05A78BN+1GdS16uzp/+1N6m\n6ux9ksddO+WWFrFEXN17ebo6XWVdrScdeRCfT/6c0tn1PAPuc3zdu7vXfM3D/bwjor0eV3tDayy+\nLQAOY+aXslLmg0C5Fh8ArF8PNDba284rgR1wJ76VK93a9XV1du/uviCua3V/3/OWd1SnD4lUeo7P\nlfiYgSOOAGbMcJvjI5J7fbXDEDa4Ogtor8fV3tCaOb77TKRHRPVENKkV7ecCX4tv9uzC8i82xMnM\nZvGVU6Tattq3DttDWI6rs67O3Qro0cOdJPNwdQI7XnCLb+pDVZX7HF91tVwTV1dnID5/tNfjam9o\nDfEdR0SPENG3iehIIppORPsS0WlE9HsAfwPgmAb8wUF1cC7Yvl06odmzZduFSFzn+HxdnapjcyUz\n/T8mWV+Lr0cPN+JT67mZVr/QoXQYOBC47jqzDq5utXKCW1avBu65x01nwN1KXbgQuOACN1kfd7Ii\naxeLj0gS811dnb16udcB9SGzHS2Bfdgwd2s9EN+OgdakM5wD4CgAywF8DMD3AJwLYAyAq5l5X2Z+\nPBMtM4Svq1MP0LA9rHlafMo95RK2Pm1a8X9MUMTn2oHnbfGtWAE88IBZ1of4fIIuiIAFC4Cf/MQu\nr+Da9uuvu7VXrsXnSnxdurinM7gOXNp7cMvrr8s0hwt2pOPqyGhVVCczrwFwTfTaIeDr6qyuLhCl\nb3CLCb7Epzo2F+IbPBh44w33EHefBPYePYScbGhpEVkfi0+dC9vARHWcLta7r6vTF65t/8//AD/7\nmZusawK7T3CLr8VHlE9wy45IfIC7vj7Hxew3EA/IDh3ulJdj8al5NReLTw/ScElncHV19urlpoPa\nr8vIvlxXp6sVMHAg8OabwEMPmQne57wpWRey9u1k8yK+lhZg6FCgTx+3NssJbnF1a7sQnzrHPtc6\nj5zNtgSrTV6VAAAgAElEQVRX16zPcf3oR0Dv3uXpE9A6dDji87X4dOJzsbZ85/hcH5Q99gC+/nX3\nCh2uQRq+xFdXJxVprrjCLNvSAowdC7z6KrDPPsC995rb1XWwnTciNwujnKhOhXLWbDS17VOyzNfV\n6TvHl4ers70Ht7gSn8v0gsKSJcA775SnT0Dr0OGIzze4RZWEUtu2tvW8MZM1xywWgEvUnJKvq3PT\nwTU6sdyozjffBM45x9529+7A+PHF+0qDj4vYlfhUuz6uzqeftsvqcG3bZ4kfde02bjSfk3JcnV26\n+Lk6A/EJXPV1CQZScK2uFJA9Wk18RNSNiL5FRNdE22OI6KjWq5YPfBcZ9bX4qqsLcjb33rBh9qCH\nbdsKRbVra4GnngIWLza36+vqrKoSAv75z+3yPXoURqkmMlPnuV8/2Tad87jFZ7s+ivj+8x/gxRfN\n7RLJy0aqStbVHangQ3yu7ks1IOrRQ0rfmWTzdnW6zvG15+AWIB/i88kXDcgWWVh81wHYCmBWtP0G\ngO9n0G4u0C2+++4zyyqLz3WODxD570dHb3pYVAe3Zo1dB0A6NmV57rWXuV1X4tN1vvVW4Oyz7bL1\n9cCqVfLZZo2okHjATmb6fJLN1QnINdlnH0nINsn6dPZEoocPsrb4AKB//0IBgpdfNrerojpdBmW+\n6Qy+Fl97rtziqq9rMBcQiK+SyIL4RjPzpQC2AQAzbwJQRpjABwM9uGX//eU9rQNXFp9alNTFzdi5\nc2HbZvG5BA+oB+7ddwtLEtmWJiISgnr2WeDf/zbroIoRu67pNmZMgfhMncGWLUK+PXvKts3i69UL\nWLu2oL9N57o6u6z6vWdP+0hctdu9u1kujjxcnX36AG+/Ldum81auq9N1jk/dZy5tt3dXpyup+0Ro\nBuKrHLIgvveIqCsABoBoYVqP2hcfLOLBLaZSWSq4ZehQ2XYZVasOGbBbfJ07y75N7aoHbuPGgsVn\nWh1cWUT19cCZZxaS79OgSNJlkl2RtYKN+Lp2LcjbiK937wI5uZCZsiSrq83tAkJ8ilRt7Zra01Ff\nDxx4oJsLddUqYMAAd+Krry8saeUSIJVXOgPgltJQDvHtSAnsQD7EF+b4KocsiO8iAP8AMJSIbgBw\nL4DzM2g3F8TTGUxBFcrVeeaZhW1b23p5M1tHoFxrJqsvyeKzER+RfaV2JQsIidhcrrrOgwfLZ9P5\nUBaf0tlGZrrFZ4KuM2AnVEWSLhafD1w7+7Vr5Rz06uW3EK06b1lbfD5zfICbV6KlxX2OD9gxLb6p\nU93kQk7ejoFWL0vEzP8iogUAZkJcnGcz89ut1iwnxC0+5eZLch8qV2f37sBhh7kFi+gWn83VCRTm\nUZRLMEkHQCwApWOXLuZ2lRVng5Lt2RN4yaHUuJ7wrusWhyLEmpqCBWWzfnVyciUzwG6hqeOzkapv\nArsiKBvhvPuuXAvfRV3r6uR+c3H7+ro6162TucPRo5Nl9QAwl3k+ZuBf/wIefNCNVHck4vMdEPkQ\nn6t3ISB7ZBHVOQ3AcEjpsjcBDCOi0UTUalLNA/EOzlSIV1l8ANCtm1v5LR9Xp0vIuGpDD24xER9Q\nGNm7wJUYdJ3V+Uuz+JS1B9hJUqFTp8J/snZ1ulp8vgnsPXvaXcTNzYW17d57z60j1ecwbYMAnyLV\nivgA4Oij02Xjrk4X4gPcgqnUgMGnEHglkSfx+VqH3/iG5MUGtB5ZGOZXAZgH4NeQ0mWPQhaifZGI\nDsmg/UwRd3X27VsI1ohDzfEB7h3AwIGFbZvF51IWShGGcicBbnN8epCNTdbX1WkjsyTiM7lF4+5L\nl6hOZSHbiC9Pi8/FPausp06dxG3o6nJ1Ib5yXJ2qPZNlFnd1uszx+WDYMGDpUr//VAptifh++EOJ\nvg5oPbIgvjcBTGXm3Zl5NwBTAbwC4GAAl2bQfqaIuzpNxKdcnYDbOnTMUq1E/79J1sfia252s/ji\nI3ubvooYXIhPdQJKJxeLT8FGfGr9N8DdvQe4uTpdCKoc4uvd2434lI5DhohL0FbYoByLz5X4FEzW\nWTmuTleo/NVly9z/syMhb1enz7JkAenIgvjGMvOzaoOZnwMwnplfyaDtzOFr8emuTpcOoHt34OMf\nl+0siU+5iAC34BbXzkgFwvhUN1GdpovFpywcl0AfVTXFxdV50EHy2UYMgFs6g8t+43BpV7k6AQkK\nOv54mQtLQ3yONmuLT8Fk8ZVDfP/4RyE9yCZbX++WGN8WkKfFp66Hzz4C8WWDLIjvWSL6FRHtF72u\nAvAcEXVGlNvXllCuxdejRyHEPA3xzsXV1WnqWHRLyWeO722H8CL1wB17rF1Wb9u2NuDmzQUdbdah\nroeCy7zdsGHy7mL9ulp8PmCWAYNtuZq4xefSrmueopLt3Nl9VXUFk/dCl3WJ6lQDPltgi4LPqh2V\nhu99UY4V5xPoEwJiskEWxDcHwH8BfDl6vRJ9tw2Awxjwg0Xc4hsxIr06hm7xjRwJvOJgw+qBJbYo\nPtXBmTpP/aEgkkLVLlaOywOrOk7XCvGqTVXWy8XV+d3vAjvvbE8FIQJ+/Wv5bEoij1dYsVVacXXl\n6oMWNcCwybsEt+jWk5rDdBm4qHQUlzw+FwLeskW8Fgqme1N/Rlzz+FymApSsaym0toA8Lb741IEL\ngsWXDVpNfMy8mZkvY+YPR6+fMPMmZm5h5jZ3e8dHvpMnA4sWJcvqwS0TJgDPPWduW93Il18ubh9T\nZ6tkhw83R2rFiW/8eDcXqmvUnO+8FhEwb5504iZXpyL/+no5xzadgeLAIJvOLsSn2p00CbjjDgkO\nMMnqVo7+/zQ0NEhEsInIdFenIn8X67dvX3k3BSmpe9nF5bppU4H4TjkFOPxwc7s+rk7APepZpfy4\nEN8XvwjMn2+XyxN5Ep/rAtc6AvFlgyzSGcYQ0W1E9BwRvaJeWSiXB+LuyDFj0nPYdFfnhAlSENnF\nfdmrl8xBpblQddlRo2R5kjTEic9W9UK165Jw6/tQKx369hWScg1ucdVZj2C16aw6cRvxERXy1ZRF\naZLV27aRdUMDsHy5DDLSzqXu6lRWlmlQovRQxOfiynUhvo0bC8d1wgluqz4AduLT81F9LL7Nm+1V\nb375S+D3v7e3mSc+CIvPh/iCqzMbZFWk+lcAtkNcm3MB/CGDdnNBc3PxzTNokIw+k1xFuquzvl46\nGFMYtt556vUWTbIDBhQKEqfpq6BKarmQyKc+lS6TpK8L9E7AlIQcJ75u3ewjfBWwMniwm0VbVQX8\n6lduUZ2qM3rjDXu7gFiIgBvxqWuXdk1060kFoJgCUeKuXFPHqwZmvhafzTp76y33yi36QMR1jq+q\nym15JMBel7atoRyLz8XV6bJWZYA7siC+rsx8LwBi5teY+WIAR2bQbi7QR+BAwSJImufTLT5A5EzW\nmd55moJmdFm9En8Skiw+lwhJV8RlbSNcJW8i4DjxDRliDl/XrYazznI/PpPVqberYCvjptr905/k\n3TZH29BQ2EcamemuTtWeifi2bZPOXrmKTedi2zY/4lNzpzbiO+KIwvNQX29uW93HXbu6W3yA+zyf\nSz5qnmgrFp/yEuxoNU7bKrIgvq1EVAXgJSL6IhF9GIDn4i4fHPSOSCHN3albfOq/t91mbt/X4uvf\nH1ixwqyv3raLxadw9NHmebOkh9plLg4wR7nGS8ANHWpPWFbnzVYwO2512sL4Vbt//zswZYpbu926\nieVpigRVLjuFND30gdZXvyrvJleniohVrk4b8XXq5EZ8eqSty3yc8oDYPBJ63ujWre6Rz+2V+HxS\nFHyIT0XtBuLLBlkQ39kAugH4EoDdAHwSwMkZtJsL4hYfIMSXtLirHtwCyMN91VXpbes3+4ABbq61\nvn0lQMJW9xIodDC2qhvq4fvhD9NrgOptAsCHPiTvLm5GQFzEy5en66xHRg4dal5wVz9vffu6DRgA\nu7Wst9vQYO5o427fQYPs108fQJmIT8lNnCjzayayVoFBBx0EnHaauaNTxNfQIIMF05xZPDXHJQ0D\nkPvYNDBT500fuNjgQ3yVntMqZx4csM9f6jKB+D54ZEF8I5j5XWZexsynMvNxAIZl0G4uSLL4dt4Z\neP75ZFmd+C67rDD/kwS98xw5UjqMpPkRZiECIum4GhvTO5e4xadW53bRweYW1R/qv/xFou1sloBO\nfGnEoFxwCiNGZOci1nWwlb7S27VFEibN/b75pl2PQYPks4urE7Dn3Ck3sQpQMumsiK+mRgKqTOdN\nJ+BBg+QecnFNDhiQPsABkueJbZVpALu+CjYPS94oJ78TcC8I4Sqr7pmwlFE2yIL4vu74XZtAvIMD\n0lMV4q7OESMk9SDtRo2TzrhxyYT6l78Up1DstJM5slRBEZ8tOd1lHi6uL2Af3eswEUPc4hs+XAIm\nTB2t7iK2zY0q9O0rAwuXduvqzO7AJOKzWXxAoUNycXUCQL9+ZitVd0n262c+F7pHYvhw4LXX0mV1\n4qupkXvuxRfT5RX695frnHbP6ffQggWFY0iDkt91V+CKK+yW0cKF5VtdWeCDIL5g8X3wKJv4iOhw\nIroSwGAi+rn2uh4S4dkmkeTqHD9eXJ3xhzBu8TU0SMeclsgeJ5JJk4BnnimVU24m3XpK6wzjD5DL\n3KFCY6MQjqlz0fUdODB9dK/aVfJDhqS7L+MWX02NBAalkXuczFyCgpQuJj30dgcPlnbTrK048Q0b\nZs6vVHpMnizbrhbf8OFmK1UPDOrfX65fGpTFp/Q1tRvXI83LEYeaq7377uTf9esxdapcP9s8nyqp\nd+ed6bmx+j27o6zkAPgRXzmuzmDxZYPWWHxvAngSwJboXb3+CuDQ1quWD5JcnXV1Ur0kPmKOW3yA\ndLQmF5hOJBMnJhOf2r+SNQUnxC2+7t3luzQrR++IevWSY3MhBsA8bxfHLrsUamvGEZ8bBWRwYepo\nlc6NjTIwSCOo+ODC1OHHq7GMHGm2rPVrPXly8rWL6/yPf4hl7zLHp/Q1WWZ68n+/fu7E52Lx6ceX\n5uVIsnDOOitdj/j1qKszE59q/4AD5D0tgEjv4CtZ5aVcazMvV6fL3GGAHWUTHzM/zczXAxjNzL/T\nXn9iZofV3SqDJIsPkI4g3jEndeCDBrkTyaRJwLPPlsrFiY8IuPHG5DbjxGdzd8Y7orFjgf/+1012\n4MB0V2f82EaOlPOQ1DHEXZ2AkEOaa01vo7paoi9dK3YMH25eRFc/PpMOceIbOtTN1dm5s3T2aVZJ\n/H6zEVTc1elDfCaLL07AO++cTHxJHevw4ell/eLtuhAfkdSHPfLI9AHftm0SfTpsWGXrerYVV6ca\nCOwoC/i2dbTG1bmIiBYCWEBEC+MvxzauJaKVujwRXUpEzxPRf4jo/4goMU6MiF4loqeJ6CkiesxV\n7ySLD0juCOKuTgCYORN4+OHktpPmzJLcdqojVB3cSy8BDzyQrq+CazSjrsNOO6V3WnFZm6tTl+3W\nTY4jaTQed3UCYvGZiE9ve5993M/x7NnA/feny+oYPTrdTR0nvv793YM6TKkd8ftNWahJHSpzsauz\nVy85l2nuQH2AYbMk4wQ1blx6Ck8ce++dfn/GiX3UqOTBng7d02Gy+Dp1cqsVqjB/PnD11W6yrmAW\nC9y1VFherk6XqkYB7miNq/MoAEcbXi64DqVu0bsBTGTmKQBeQnqgTAuA2cw8lZmnuyqdZvHtvHPp\nA5vk6hw3Lj1CMd4pp1W90Jc6AoC77pK5lKRozXg6A2Ce19q8uTj3aaedzBafjoEDZb24NMSj94YP\nBx5LGHIkWXzjxwMvvODW9vjx7lbq2LHpc3FxWZO1Fb8v+vSRTjfNnavrbFqXL95uz55CQEnyasCg\n5KuqgA9/WGqjJkEfYPhafGn5eUmd8LRpcu2SrNp4u4cdJu7fNOj33Nix6e5kRXw+Ba2//nXg8593\nk/32t4FHHrHLMbsVjdDlgexdneq6BIsvG7TG1fmaekHm+XaJXpuj71zaeAjA2th39zCzGtfMA5C2\nmAuhDP3TLL6kYtVJFp8tiCBOfC+8ANx3X7GM2r+ay+ncWfafNAJPsvhMc3GLFxdWAQDEynElkfHj\nJYouaX4tyUL5+MeTgx6SLL5x40S3pI413vauu5pdna5kFpc1RUnGLb6qKmDGDLcAkE2bgL/+Nfm3\nODEA6feQ7uZUMFnKuqtzxAiRS0v+j9/3Kno2PohT99vuuxe+69RJBkVJrt/48U2fDvznP8k6AMX3\n3Nix6ddOJz5XV6dP1ZTvfQ/46U/tcipfk9nN2srL1ZmnxbcjBQ9lhSyKVH8cwGMAPgbg4wDmE9FH\nW9tuhNMA3JXyGwP4FxE9TkSnuzaYZvFNmiQuJf0mTJrjs7mqdKjKHmnEpy8Tk1Y9Jon4evVKnxu5\n8spi0hg71t3S2n13Iagk12hSvtbMmckElWTx1dfLMSZZiHE9dttNXJJJI/34Oe7fX4JhkoJ94rJ9\n+6YPApLSXEaOTLbu4xGus2alF1NOGmil5TUmrVw/blz69dOJr08fiapMGzDE7/vqatnXQw8Vy23f\nLhbs448Xf59WhCBOfMpaNyXpuwR1vfeeeEF8XJ2+ye6u1pOqmJS1Fefj6szL4lu2TO6DjhYtmkUe\n3zcB7MHMpzDzyQCmA/hWaxslom8C2MbMKWEf2IuZpwE4AsCZRLS3S7tpFl+PHhLyrpNPkquzvl46\nm6Qlh+LkoGojxkfh6uHQy3r5EJ+tRNWoUYXPEyaIK9CFGEx66PtXGD8+ec4syeIDJBI0yXqJ61Fd\nLXqkyep6VFWlW1BJbtGnnkoO4EkivlGj3NZgPP98uSeSzmfSQCst2leP6FQwuYh14gPk/CZVIFJ6\nxO/7s84qJbOkwR4glu9HE4az8Xa7dJHr4ZK60quXeAyS7s1yXJ15EJ+6h3yIz9U1qqxJnyLVWVt8\naoBiigNoj8iC+KqYWY89W93adoloDoTQTkqTYebl0fsqAH+GEG4iTjppDi6++GJcfPHFuOuuK7Bq\nVdP7vzU1NaGpSbYnTwZuuqmw/d57wDPPFLaVfO/eTe93tPr/mYF58wrbtbXAccc1YcGC4v8vXCjb\nNTWF/yvC0dsDZP9AU3Re5Pe33mp630UUl+/TpwkHHVTYfuSRJgwZ0oSFC5P13bix+P9dujThrrtK\nz4/qsPT/9+0LrFjRhPvvL5Z/9dWm9ztPXX7qVOC220rP56pVTe8TlJJXUbbx41u6tAmvvFL8/7q6\npvfda3H5t94qbA8dCuy2WxOuu670+NSASP//rFnAHXeU6hs/3nnzmlBbKwEu8f0vWtSE1auL5Wtq\nkq+HLNVT/P833mjCkiVN74/Idfnt24Gnny5sjx0L3Hdfqb5NTU3vE5T+/2nTgL/9rVj+gQeasH17\n6f8//GGJJI4f34MPlsr36dP0/qAlLr9pUxPmz5ftxkYASL4eivjWry99fpKOD1DEl/570vkz/Q4A\nDz0kx6eIzya/ZUsTiJreJyqTPDNQXd2EJ5+066ssvldfdT8+l+1HH20C0IQ335Tf5syZgzlzpL9s\n12DmVr0A/A+Af0JWXZ8DcU3+2OP/IwAs0rYPA/AsgEbDf7oB6BF97g7gYQCHpMjyQw/x+/jNb5hP\nPZUT8Z3vMH/964XtIUOYX3mlVO5DH2K+7bbS7wcPZl66tPi7Z55hHjeu+Lubb2ZubGRuaSl8N38+\n87RppW3+9rfM8ohIW8zML7/M3NBQ/H+FAQOY33yz+LvPfIb5l78slV2wgHnKlOLvfvUrkY9j61bm\nTp1KvweY580r/u4LX2D+xS9KZR9/vHR/zHI+b7+9+LvzzmP+8Y9LZc87j/nSS4u/+8EPmE85pVR2\n7lzmT3yi+LvPfS5ZtxtuYD7hhOLvmpuZu3Zl3rCh+Pvt25mJir8bNUquYRw338z8sY8Vf/fMM8xj\nx5bKPv0086RJpd+PHs38/POl3++8M/OiRYXtv/2N+dBDS+WYmQ85hPmuu4q/W7WKuUeP4vvotdeY\nhw4t/f+mTcxdujC/917x92+8Ifecjq98hfmSS5L1GDaM+dVXC9snnijXKQ51Ls4+m/mnP01uKw71\nnLjKHnKIXe6tt+RZratjfucdu/yAAXJOX3jBLrvnntLunXfaZW++WXQ+5xy7rA8WL5Z2b7qp9Deh\nh9bxQ1t9ZbEC+1cBXA1gcvT6NTNf4PJfIroRwCMAxhLRUiI6FcCVkNUd/kVEC4joqkh2IBH9Lfpr\nfwAPEdFTkACYO5g5pbZEcdBKkktLYfJk4Ikn5POmTTL5Pyyh6mhaDlSSm2inncTVqPvQt28HDj20\n2A2nLL64uyzJ1TlqlFiTSS67JPfs1Kni4ovDx9WZJAuI+yvedpq7bOzY5Ao5SW2nBaIkzTXuuWey\nSzJJdsSI5ICKpPuiqip9yap4uwceWDovBiS7OseOFRdj3MWXNDcKpAe4xF2d6vwmIcnV2aePHIee\nipH2fHTtKtHE8Xsj6fhs+ZK6HoMHJxeEUO36uDpdcfvtBV1s0F2dLnNxzHJNXGVd3aJ5zfGpZ891\nLcX2giyCW84FMJ+Zz41ef3b9LzOfxMyDmLkzMw9j5uuYeQwzD2fmadHrjEh2OTMfFX1ewsxTWFIZ\ndmHmH5n2o6cppAW3AMDBB0uI84YN0tmNHJkeCJM0RxPviACJ2BwypLjz/OQnSxPWe/US2TiZJaUz\nAMnpF0o+TjoTJ6bngsU78J13Bv7979K5nyQSAcRdFg8YSevA1WK+SUES8bb79AFuuqlUzncuLon4\nktIf0jr8pHSQJKIeODCZqJMIp1MnGWC4FEwA0gNc4vfbiBFCIklRuWn3/YYNxfeyCipJQlKZs6Tj\nMwXkJCX0J1071a5tBfhycOWV8u5a99J3js+H+GprKxvVqdozFU5vj8hijq8OwN1E9GC0Hl//DNrM\nFDqZpAW3APKQTZwouVtr10rnm4SxY5OtoiTiA8wh6TpUyL+OtIdt5Mj0DjzeeQ4enJz+kNaB77df\ncseVRHzTp5dGEqYFtwDJwRpJepxwgoTPx6MDk87x4MEy/xR/eJPaHT48+bylEUOSxZc0COjbNzkv\nLu1+Sxo8pRFfWoBL/Fx06iTkl2ShJhEUIIORW29Nb1NHUnWjNOJ78cXk8x8/H7vvDjz5ZLpcHhaf\n2r9PlGYewS0tLe4kmbfFF4jPE8z8HWaeCOBMAAMB/JuI7mm1ZhnittsKuSomiw8QC2bBAjH94xF2\nCmnuGbV6dhymEbCOsWNLCVLvKFyqrKSVWVuxorRjTrPidtqpdBSe5upMSn9Is/iA5M4zSY9u3ZKr\nziR1zNXVyUWl01ydPhafq6tzjz1KUwOA9PttzJhkSznN4ksaOCXJp60tmUZ83/528baN+OKeg6R2\n+/aV85NkAcfP85gx6USdl6tTXTsfV2dNjbuFmKerM2uLLxBf6/EWgBWQqM5+GbabCRRJmCw+QIjv\nzjuTc6oU+vWT3+Mj9vfeS+400goCxzFqVHJCcb/obJZLfN26FapvxJFEfCNHJhNfkuygQdJZ6mRi\nsvgmTHDXI8nSSSPVNHdnvN3+/aUjjZcYSyO+pLnGpEGAKkAQ78TS7rekuqg2iy++3ySSGjgwub5n\nmh79+hW7zG2uThfiI0on6/hAoHdv+S5eyUbpm4erU90TruSUVzpDS4ufq9M19cEHwdVZJojoDCJq\nAnAvgEYApzPz5Na2myX22KMQ0GCz+D7+cSnbtX59usVXUwMccURxUEdLS3rb06YVu3OmTAF+85tS\nuaSE6eZmCasHijs+H+IDJHQ83rmkWXG77QY8+mjp90nkVFUl51fvPE0WX5K1nKZH0kAgjVSTiC+p\n3aqqZNk04ksqCJ40COjaVWSXLSv+Ps3SSlrvL+3a9e0r73E9koivsTG59F3avXnwwcC99xY6QJPF\nN3GiWJO6+zmNUIcPT57LjcsTyfWIW31tzeLzJb6sA2G2bxeSDBZfNsjC4hsK4MvMPJGZL2ZmB9vm\ng8V++wFXXSWfbRZfQ4O4HB94IN3iA0pdSqrDSCKHXXaRDlw9wPX14kKLI61D3mknGZn37Fn4Pon4\nWloKSbFx9OqVTHxJ+u6xh8xz6sSRRk5KF916MVl8aevtpVmeScTXGosPSA5YSSO+QYOkU453eq7t\nmioFLYyVck8jPmVBxa3fpHPRu7d7kA0gNTv79Cm4wU3E162bnA/9mqQdX9p1TpJPu+995/gkL9De\nifvO8fm4On2DWzp1ck9gr60Nc3xZIYs5vq8zs6E6X+UxZ06hk1m/XojHhE99CvjDH9ItPkDIUQ/q\nMHUYnToVVmPfulVINS0I5oUXih8a1SGvXCmdlEJStZKkwBa9bS1v9X0kdeCNjbJPveNKI0lAXGD6\n/FZaBw4UOk79GNNItbXElzbI8SG+MWNkwKFWFzfpm9Zukg4jRogLT593NZ03V7fvnnuKBRdHGvEp\nXZSr2uTqBErnPNPa9Qn2Sbp25UR1KlKIz1vG4WPxKfm2ENySB/H5lE1rT8hyjq/NYuhQ6TSee05y\n+tTIMA17722e4wPEivzXvwo5grYOQ82PqE4pqfPu1Uvk9BUS0uYNBw0Sl5ZeYNbUcR5zTGk1epMV\nl5TPl0Z8s2YVB6yYBgEjR8p50kk7jVSTalqmHWNS5/nee8UrVSgkBc2sWJEexbvnnoX8TpO+SYEl\naRYRkbjAdXe56frF58yYk+V33VXIN+4SMxHfyJEFwjZdO8Cd+GbMSB5oJZ2PpOWiynF1KlJIcvUm\nwdUqA/JLZ3CVfecdWeswL1dnIL52iPp6YP/9ZbmUv/zF/mBMmybvu+6aLjNkiITcq2VrbB2GyrtT\nVlSa7EEHFXcYGzbIDR9HdXXporimjlPNucTdl2lktuuublYOIHro83YmPQCxBuK1TtNcna++Wrzv\ntPOsAnJ02bTBSNKKFS+/LISYhMmTS5cnStI3qQaniXAmTiwdMLhafKpQQVyPHj3kfo+7wU0u/j32\nKJUp4GMAACAASURBVHgvbPfxuHHFAS5pxzdhgtscH5A8x1eOq1MR06RJZjm1f5/gFp/6m67uSx/i\nW7RIClHk5ersaMsdZRHcchYR9bJLVhb77gucd558/uIXzbJ1dZIC8YlPmOUmTiy4UF2I77nnChVc\n0jq4D30IuOOOwvaGDemu2XhovolwunUT/eLRjGnEN2FC8SjcRJJqjk93m5jORe/exYOPlpbktuvr\nxerWXa5p57mhoVTWRHzxjvbdd9PP85QpxUvtpA0CkkLzTYQTX17KdP1GjSqNnE07x0nEbgrqmjy5\nQGZpHgaFadOKz4Vp7nDlytJO3XWOT8n5uDq3bwc+8xn7orHlBLd07uxGwD7BLcrV6aLHe+/JICAv\niy8Qnz/6A3iciG4hosOI0rrHykLv8Hv3tssfd5zZdQkARx4JzJ0rOX+XX56c26ew886SJqHcVWkP\nxsSJ4t5TBJlm8QGla9EllSvTMXhwsYtx27Z0+fjq2KaOtnNn+V11+ibLRemtR4Fu3ZrskgRK5/lM\npBrvQNOIr3//0sCLTZuKl4nSMXWqjLhVNGPaIGDYMLFy9M7JRDjDhxdbiCbia2wstpJtxJc2Z5YE\n3ZpMy0VVGDCg+NylEXttrcyD65Yyc/r6hG++WVzWT09nePdds8dB/0+PHvbyW+UQX3zwY5LPw9XZ\n3OxOkj4Ic3xlgpkvBDAGwLWQItUvEdElRJQQt1g5fOtbwMUXA7/8ZXZtTp0qpLR0qX1RS7VU0OWX\ny3vaemXdu0s6gZrnMxFf3OKzzTPusktxJOG6dcWL1uqIR4Fu3Wqe8xw/Hrj+evlsI76PfQz47W8L\n26b51Pgxmtp2Jb5u3eRB1yPZTMTXo4eQiX7ukoiva1cZVOlWnIlwDj9cysPpnU/asal21ZyuzTr0\nIb7Bg2UO6Z137J6LeLqEqd1ddy0mdkUi8XNXWyteA11nNWDo1EmO0yXqsLlZnh+bbDnE19iYvshv\nXD4PV6eyDoPFlw0ymeOLKnmviF7bAfQCcBsRXZpF+1mgZ0/goouAM87Itt3+/ZOj1+KoqQH+9Ce3\neYgDDijk0ZmiUOMWn8lyAkpHrWvWpFu/ffrIquLKytiyxdz2975X6ORWrzYHEO27r7ji1APvY/Ft\n3JhOUOPHFxckTyM+Iung//SnwnebN6e3C0hpNrWIrsl9OXJksbvTJNuzpwwwlBVuIjMVYXzDDfJu\nIqgk4jMNGKqqCsEzNldnz55yDVwqIcUrAJnOxezZwD1avSedUF1WYVeE0K2bO/H51Op0dbnm5erM\nO50hWHyeIKKziehJAJdClgfahZm/AGA3AMe1tv22juHD0xfdjGO//eT9xz8uLFKbhJkzgXnz5LPN\n4tOJLy2KUSFOfKtXp1t806PVDe+/X95tFt/EiRKhuG2bDAQGDkyX7dpVfleEZiK+ESOAm28ubC9d\nKlG6STjkEOB3vys8zCYLeLfdxPWsYLL4gMLK4kDygrEKcavaVjBBLyBuiyT+xjcKASO+xGcbFKnq\nQjZXZ1WVyPzsZ7JtsvjiuaamczFxYjpJugS4qHSUrl2zd3W66qDke/VKDuxJkvWx+NSUQpZQA4Zg\n8fmjF4CPMPOhzHwrM28DAGZuAXBUBu23aUyfLhPqAHD11WZZZV3Z3BUzZojFt3y5fY5PdwNu3Wru\ntBTxqYd52TKJTk1CbS3whS8UHuBbbjHXGx0/Xka6TzwhnY9tfnS33YAHH5TPpg5/5EiZJ9q8WYhs\n/fpCJZM4Zs2Sc6AscBPx/epXxdbhpk3mvE09b9Kkr6r1qmAiBqB4lY2NG80DovhcnM8cn8vA5dln\n7a5OANhrL+Dhh+WzzYWqW+smiy/u0tZJsq5OrrsJiviSCjXEUY6r0yfIZsaM0nq0aW37zPHV1SWv\nVt8aBIuvDBBRNYATmDlhhTOAmR0u/46N/tpaFEcc4fafNItFobFROrmrrjIT35AhEk3p4jIEJIqQ\nuVBl5fXXk9cbVDjooIJVZFuQmUishiefNHfeCvvtV8iNM+l9xBHihvvvfwvEkBY+RVRscZmIb9Ik\nyblTI2gb6QwbJtG2LS1+xGerFDRpUoGAbTroBb5NBDVggNw3uoVic1UrPWyuTkASxNetk88m4ps9\nWwobqPlsW6CP7r3Qz1taGTYdiviSSszFUU46g4+rs66uNHo6CS0tYkm6WIfNzTLlkXX5tjDHVwaY\nuRnAi0Rk6D7bN1TS809+km496Vi8GDjxRLvcSScB3/++jF71UmU6amullJmqD2lzdRJJwIFyd65b\nZ45wnTmzNH/NhH33Bf7+dzfi091xNhffhAky/2QjBkCWuVFzcRs2pMsrd+trr8nDb3N1jhgh5/eB\nB8z6TpokVpm+fprLaiCA/fjGjRO3+tat5vlAouKkdMA+KNp7b7HAt2yxE9+MGYVBi4n46uqE0FRS\nv2kQoNJnVIFt/bxlTXx5WnyK+FzdorNmua3c0tIiKTtZF+wOrs7y0QvAs0R0LxH9Vb0yaHeHwLhx\n8v7Zz7rJjxljtgAUzjlH3rdtM5PC7rsXEt5trk6geJ5v/fp0axIQy2HduuLqMLa2H3zQTCB622+9\nJcS+dauMfNOgVha3kRMgxK7mzNasMQfZKPLdskXOm4mgBgyQOcQXXjATn4rsVAWobRafmtvatMlO\nfHV1hRQBm0ty6tQCOTHbia93bzm3y5fb76GGBmlz40Y/izatLJw6tunTC0FdvhbfokVCNo2N+RCf\nS4CNkq+vd7P4lKyL+zJviy+4Ov3xLchc3ncBXKa9OgSGDpXoR1PHXQ6ICgEmJhx4YKEUma1zA4Sc\nlBVnSo4HpOMZMEA6w8MOk/qlJuy7rzyYLh1E374SDPPoo2JZmshdLdDrYvHpqz+YolaBAvG5ECog\nbtenn7ZbqLvuWliNwzbHV1sr1s7ChaJvmnWv6/zaa24FE1TQlcrXNBE7IG77ZcvsFh9Q8DTYjm+X\nXQrEZ5OdMaNgrftafHvvLe9ZW3xKXuUT2uBj8bW0SLu2YBygQHxZW3zB1VkmmPnfAF4F0Cn6/DiA\nBcY/tTMcfXT6vFNrcMEF9rk1fcmjrC0+QB62xx+XB27wYLOsCg5JWlg0DjU3es01Bas5DWqBXhfi\n0118b79tJr5Jk6SMnUu7gBD7v/8tCdwm+f32EznA7uoECu7OxYvlWE1QSfI24tPTQFwGRIAExaQV\nUI/jwAMlHcQ2aNCJz2TxAcWLGut5rn36uNffVO5AU/SjelZdrrkiBh9Xp6tlxiztulh8LS35WHyq\nalKw+DxBRKcDuA2AimkcDOD21rYbAHzkI5J7aMKUKeJ+27pVEmxtFsO4cRKduHGj20oVzz4raxSa\ngmx0zJwp7lcbOncGvvY14Pbb7ZV0Ro+WTtzl+EaMkId48WJxperBR3Ecfrh0yq4W36hRYuU8+qiQ\nYBp2261gVdtcgUCB+FaulAAkE4YOlbZtgxxV5xSwW6gKJ5wg19k2eALEAzBvnlyThoZ0uV12KeR3\n2gYBw4bJIKulBTj9dOD3v5fvXSw+haoquZ/itWB1KKIhsrsk8wxu8SG+5ma5hkTpxS/KgU/CfXtC\nFq7OMwHsBWA9ADDzS2iDK7C3V6jV1W+6ye7aA+QmV661jRvtLtr//V95X7nSjfjuvVesBhco8kjL\nJVRQHd/q1fbjIxJrRC2uajq+oUPF1blggdvoX83dXHaZOU9Rj750tfiefFLmU00kAogbde5cIXXT\nIGCnnQqLxrpafAceKO82fYFC3t8775gHT6NGia4bNogeJmty1iyx0uNRji7zdjps7k5FHOvW2Qd+\neuUWFx3KcXW6EKqylrNemNcnpaI9IQvi28rM749BiKgGgENlvYCs8MUvCkGtWuVWh3TKFMnD6trV\n3sl97nNCUMuXuxFft27mfDgde+5Z+I8JtbXScb/8stvxjRol8579+5td0F27AvvsI8FBLhYfUcEi\nS8slBMQlvGmTELVtXguQItHPPy/uORtBHXigBK7cd595wNCnj8zz3XOPPYdPoV8/CeCxrW4ASNub\nNwP//KeZrKurhSSfecY+p1xdLcf2/PMysPjc5+R7F4tv6NBC0QcbSe2+O/DhD5vbU1DEp/S25RMy\ny720bZudTJjletfWulWm8S3a7QKf6jHtCVkQ37+J6BsAuhLRwQBuBXCH5T8BGWL//WVZmR//2L7W\nICDup69+1Y3IAOkMAXd5VzQ0iPV0zDF22Y0bge9+12xpKcycCfz5z9KR23D88VIGzIX4gMKCu6Zc\nTCKxXh5+2M3V2bWruGhdMW0a8Otf2wcYJ50kVW9sOXw6/vlPyb+zoapK3Kl33in5nibsuacQsIu7\n/KCDRIedd5ZC8YAMNpRbNQ3btxfSiWwWH7N5ybG4rKovOmRIIXXIJl9XZ6/tqQZF/foV0jjSoC/T\nZCNfH/iUWGtPyIL4vgZgFYBFAD4H4O/M/M0M2g1wRL9+Ml/FbJ8DAwodiutcwXHHSWfo4g70xbnn\nupGZinB1iXSdOlWI0ubGAmSFjU2b3AI6gALhjRxplhs7VubYXBLCAbGeXPJAAZlD1N/TcOCBQtSu\nrk5fqM76gAPMcsccA9x1lxvx7bWXDOL0eUl1ro89Nv1/+jHaiK+lxb50kQ7lNfAhPpcavkrWlfiq\nq0U2vrJIa9BR5/g8Ln8qzmLmnwG4Rn1BRGdH3wV8QLjtNrfK9IB03pdf7pZPCEgVGVWzs1KYP98e\nSKEwcKAEBe21l11WWVrx1enTUFNjLpSt63DbbWKt2OYwgYLr2QVHHinvBx9slhs3Ts7ZkiVurk5f\nXHGFW9WRPfeUSOKVK+2Dkd13l/nnESNKdU5a0R2Qa7dmTTHxmVyjzO73vr4ckgvxAQWX+PLlYrna\n9Ojb105mytU5YECh8lIW6KiuziyI7xQAcZKbk/BdQI7o1g047TQ3NxUAfPnLuaqTC1xID5COx5YG\nomPZstIVy01wcYsecwxw6aVCZi7E52rtAYXyaaZyc4B0qtOnC6nmYfEdfribnCocfdVV9vuzrk5c\n8fPmFRPftdfKCiBJayGqCkDqGBsbCwUEkuAy76qg78+H+AYONK/PqfTwsfiqqsSSzJL4gqvTE0R0\nIhHdAWCkXrGFiO4HYAgmDsgL115bWPcvwB2DB7ulYPhg/Hjp2O6+2434fHHUUW65o2+8IdZ9Hhaf\nL+bPN1tACmrOULeATzlFiOTWW0vl1Vyucim7uDpd8259iE+3DuMrU5jaVkUiTFCuzqwtvo7q6mzN\nHN8jkAotL6C4Yst5AA5tvWoBATsuqquB886Tz9OmVU4PlVZR6QHRN74h7zNm2GXVXJ4+j1pdLYUi\nPvWp0uT07dslr1ARVJ8+ZtehcjHa5kiVbDnEpwq229pWQULx1TTi0F2dLut/ukK5OoPF5whmfo2Z\nmwA8wMz/1l4LAPwgMw0DAnZQXHihjORdA2fywNy5Et155ZWV0wEAfvAD6ehtVXoAIaTt20tTbSZM\nkGChk08u/j5excZmFSmL769/FVkTdOIbPNhOfEp21ix7gXelx/DhhSWv0qBcncHiywZZRHUmTbE7\nev8DAtov1Ai9kjjxREnXcElKb0tI0nf//eX95puLUwW2by8lPpPrUFlatbVukc0+Fp+SVYtEm9be\n9IkAVa7OMMeXDVozx/cFIloEYDwRLdReSwAstP0/ICAgwAcHHCAd9Yc+JIEuCtu2Facn9O8vUZ1p\nnbkKbunUyb6iue6+bGwsrKKRJquIr1s3iWA1kZQiYEXU+r7iUOQ+dKikyZhkfdBRozpbY/HdCOBo\nAH+J3tVrN2b+ZAa6BQQEBJTgtNOk8IGK3Iy7OmtqpMJPWqTkpk2F+psbNkjwTxp0MlNJ7GkRo/GI\n0xEjilegj0O5Ovv3F+vTJKvIvW9f+U9WuXyhZJknmPkdZn6VmU+MVmDfDClV1qMjL0wbEBCQL1Sl\nnyFDpN5m0koVpqjK3/xGEvtraiS9Qq0mn4Q4mQ0Zkk5QcdmddjKvVKJXhZkwoXjh4DjUMRLJPKnL\n4rUuCHN8ZYKIjiailwAsAaCWKLqrte0GBAQEpOG3v5X3W24pneMD7OkEauWK/fc3d/pxMjvoICnT\n5iK7005mMtMT6UeMKOiUJNfcXHDnzpoltVqzQCC+8vF9ADMBLGbmkQAOBDAvg3YDAgICEnHqqVIZ\n549/LJ3jA+zEt3WrvNtWVo+T2axZhfUsbbI24tPzCYcPTyc+dXxKdu+9ZUWRLBDSGcrHNmZeDaCK\niKqY+X4AGacDBwQEBBRj+nQhoRUrki0+U2CJIj7bagfx8mYDB6bPr8VlXSw+PQo0zYUad+WOHy8L\nM2cBFdUZLD5/rCOiHgAeAHADEf0MQIYLZwQEBASUYsgQqdH5/e9L1SIdNovv5pvl3ba+Xby8WZ8+\nkmyeFFUZX4ljzBhZEzEtpUEnytGj05PYt28vtmhHj5Z2n3oqXW9X6MSXVaTojoAsiO8YAJsAnAPg\nHwBehkR3BgQEBOQGokJE5vnnF/+WRnyqc99lF3m3WXxx4uvdW3L/Hn44WVbPP+zTR6Iwn3suvW1l\n8Y0enR4IE7f4OneWAB/XBZ9NUMdXXW3OOWxvaDXxMfNGZm5h5u0A7gRwZeT6DAgICMgVZ58t75//\nfPH3acSnlolSBNW9u9nii1txNTXAZz+bPM+XVPx68mRZhDcJuquzXz9xvyZFmCZFrZ54otSBbS2U\nDs3NwBNPtL69HQWtSWCfSURNRPQnIppKRM8AeAbASiI6LDsVAwICApJBJK7A+KLDgwdL5ZS4+05f\n5w+wB7fErTgAmDgRePbZZNk48aXJxuWJ0q2+JOLbe2/gsceS3ZPbtkl7LktG6e5WUx5he0NrLL5f\nALgEwE0A7gPwGWYeAGBfAD/MQLeAgIAAK5LKmw0bJtVT7rmn+Ps48dksPh8yi1uHJlmgNAp08uTC\n3KOOJOIbNEiOO4ncVDk3lyR35W496SR7FZv2hNYQXw0z383MtwJYwczzAICZM0qtDAgICCgPRMAl\nlwA/jA3Bkyy+cokvbm0lWYe77CJu0bis2taJ79OfTp47TMpTVMWtk9b8UwSmIldNUORbVydVbDoK\nWkN8+lTo5thvHSg+KCAgoC1i5szSdII48Q0aJKXNNsd7sAhJVlz//vIeLyydRJITJgihxOcbk4hv\n4kRZRipOkkl5igCwfj1wV0KpEEV8LgW4laszEJ87diWi9US0AcDk6LPa3iUj/QICAgLKQmOjuAL1\n2ppx4uvSRSyntIjKJDIjSnZhJpEkkbhd4/U9k1aSb2yU7+KL6Ca5OgEpW/bd75Z+72PxKVdnID5H\nMHM1M9czcx0z10Sf1XYFVyALCAgIkPk7QPL9VABLnPjU72mFp5Pcl0Ay8aXJ9uwJ3H578XfxZHdA\nCGjs2NI6nGnEpxBPPve1+ALxBQQEBLQTEEmC+/TphRJfq1aV5quZFphNsviAdOJLkj388NK5OD2H\nT8cuuwCLFhV/ZyO++fNL5QH3Ob7g6gwICAhoR+jVS0jn4x+X7aOPBp58sljGZvG5El+SqxOQ1RTi\nEZZJrk4AmDKlNEcwjfgefxw45JB04vvoR2Ue0ATd1WkK8mlvqCjxEdG1RLSSiBZq311KRM8T0X+I\n6P+IqD7lv4cR0QtEtJiILvjgtA4ICNiRcPbZUrfz3nuBXXcVMtQxbFh6DlsamSVFdqa5OgcMKLX4\nklydgBDf008XfxcvWaaw++7AKacA999fKq+wdm3p/+J6KOKzkWR7QqUtvusAHBr77m4AE5l5CoCX\nAHw9/iciqoLkER4KYCKAE4lofM66BgQE7IA4NOphDjoImDQJ+PnPi3+fPLmUbBTSyKxfPyEjvRB2\nmnU4YYLM2+l5ciZX5zPPFBOqydU5a1ap7vp+bPN8ioAbG0uDatozKkp8zPwQgLWx7+5hZuWFnwdg\nSMJfpwN4iZlfY+ZtAG6G1AwNCAgIKMLYsYXPN9wguXs6Jk8WYkoiiTQyA0pXSUizDnv0AIYOlVQF\nhTRXZ329EKpKQgfMxDd4sKRK6AEuPsSnCHjgQHEBZ1H/c0dApS0+G05D8qK2gwHoNQuWRd8FBAQE\nFKFzZyEalcxeV1f8e7dusixQUjFpE/HFV0I3ycYXsE1zdQJCknrdTBPx1daKHvo8n6/FR1TITTz9\ndLN8e0GbJT4i+iZkrb8bK61LQEDAjo/zzwfOO0/mxuKYPTs5GTzNigOAnXcujsBMc4sCwF57FZNZ\nmqsTAA48sDgAxxbVefTRwD//WdjWj8PV1dm5s2ynJfK3NyRMmVYeRDQHwBEADkgReQPAMG17SPRd\nIubMmYMRI0YAAHr27IkpU6Zg9uzZAICmpiYACNthO2y38+2qKuCoo5rw1FOlv++zz2zceGPp/595\npima+yptb6+9gF/8oglNTbLd0gJs3FjY1uUPOGA2zjgDuO++JlRVAVOnzgZRsr5btgBvv13YXrQI\nqKlJP76NG4Ft2wrbL74IzJw5G/PmAfPnN2Hz5vTz8+KLTVFE62wATViz5nrMmYP3+8t2C2au6AvA\nCACLtO3DADwLoNHwn2oA/wUwHEAtgP8AmJAiywEBAQEmrFzJXF/PvHx58fdz5zJ/8pPJ/9m2jblb\nN+b162X78ceZp01L38fQocwvvyyf165lbmhIlrvkEma92/rtb5lPOSW93RtuYD7++ML2OecwX3YZ\n8wEHMN9zT/r/mJmvuIL5rLPk87nnMn/+84Xfor6z4hyRx6vS6Qw3AngEwFgiWkpEpwK4EkAPAP8i\nogVEdFUkO5CI/gYAzNwM4IuQCNBnAdzMzM8n7iQgICDAgn79gGnTgIULi783zdvV1Mj8mgpaMbk6\nAYnYVO2bXJ1nninvKgXivfdkLi8N3boBf/xjwa2p0h9qa93n+ACJeA2uzg8AzHxSwtfXpcguB3CU\ntv0PAONyUi0gIKCDoalJXvHcvDTiAyQa8q233GQnT5Y5wWOPTY/qBCSyc889pcD2oEHApk1Cbmk4\nLFr99KmngBkzhPiqq92IT9e5R4+OU72lzQa3BAQEBFQCr71W+GwKbgEkneG449xkd921UDrNFNUJ\nAKNGFZLqbcTXpQtwxhnAo4/Ktm7x2cqW6QTcv3/pihPtFYH4AgICAlDIybviisJ3Nvflyy8XrCqb\n7IwZsmq6kk2z+ABJr7gxime3ER8gq7e/+qp8bm4W4rOtNQgUE9+gQcnr+7VHBOILCAgIgCS6X3kl\n8MtfFgpZ29yXF10k75s322WHDpWandu2mV2dgKwlePfd8tmF+EaNKuQhKouvocFehky3PIcNE+Jz\nKW69oyMQX0BAQECEL35RKrKoldBtZHbxxVJf84kn7K7OmhpZ+2/hQnu7hx4quXUbN4oFqrtfk7Dn\nnlK0GigQX329e5FqQFyjI0cCixeb/9MeEIgvICAgQMNJJwHXXCOfbWQGSHDJPfekr5Su4+STgblz\nxULs2jVdrqZGllNSBDx5srndnj0lMIW5ENxSX19c+iwJccszadWJ9ohAfAEBAQEaTj8d+MtfZNHa\nzZsLVU3SMH26WHwbNgjZmDB1qswlbtxYWjM0jjFjZN6uoQH4yEfMsrW1QtLXXluY43Ox+OJBNuPH\nly6E2x4RiC8gICBAQ2Oj5LQ98ADwyisyf2bCrFnAvHkyP9bQYJadMkWsuLfeshPfiBHAI4/IHJ9a\nTd6G008vWJ6+rk5AiHnePLd97cgIxBcQEBAQw5FHSlHpxYvF8jJhwAAJXHnsMTvxDRkixLpwoZ34\njjgC+N3v7LU641i2zC+4RSe+mTPTl2hqTwjEFxAQEBDDoYfKun3331+8rFEaGhpkyaOBA+2yr70G\nnHuunfh22+3/27v/2CqrO47j729Fwq/S9kJBTOXCGItIN4GIEtvBQo1MLYaNECj2hz8yTTYX4xQ1\nEJSKg6BNptnmxBAcUp2oM1Yp25AJBYwCilMRlgzRLhYYg1IoMtTSsz+e57a3pfe25Udve5/PK7nh\nuc9znuec26Z8c84953y9Xh/EnwEa8e233u4zX3zR/B1fZ4c6hw3zkteePNl+fT2ZAp+ISCtXXtl8\nPHx47HIRFRXw3HPeQvL2zJvn/TtlSvtlL7mk/TIRvXp5vdPa2rMf6kxJ8bZWi84OkYy6ZXYGEZFE\niszOfPLJ9md1gjer8tZbO/bs22/3hiPvuaf9sgsXwttvd+y5ALNmeft2dmZyS+veZG4ubN3a8Tp7\nIgU+EZE2fP11/M2hz9bllzfvytKeG2/0Xh11/fXeRJihQ89uqBO8pROdCbY9UWAD34gRI6hub1Wo\nJFw4HOaLyF5MIl3oQgS9Cy01tXmbstOnvcAXb5eYtrZZGz0ali+/sO1MtMAGvurq6ki+PunGrCPf\n6ovIGS66yAtiGzfC1BgpvdsKiqNHJ//uLZrcIiKSpG67DR59NPb1toY6hwxp3qs0WSnwiYgkqXnz\noKoq9qL0trJEmMEVV1z4tiWSAp+ISJKK9OaWLWv7eqzv/7ZsuXBt6g4U+OScVFdXk5KSQmOyj42I\n9FCVld7+oKdOnXktVkLceHkFk4ECXzc0YsQI+vXrR1paGqFQiNzcXJYvX96hyTidDUQ33HADixYt\nOuN8RUUFw4YN69BzNAFFpPuaOBH27PF2i2mtvYS4yUqBrxsyMyorKzl27BjV1dU89NBDLFu2jDvu\nuKPde51zmFmHZ6yWlJRQXl5+xvny8nKKiopI6cjqXRHptjIzYdu2ttfmtZcQN1npf7VuKhK4UlNT\nyc/PZ82aNaxatYrdu3ezbt06JkyYQFpaGuFwmNLS0qb7pvj7IKWnpzNw4EC2bdvGvn37yMvLY/Dg\nwQwZMoTCwkKO+ytbZ8yYwZEjR9gatVVDXV0da9eupbi4GCBufa2NHDmSt6P+wkpLSykqKmp6/957\n75GTk0NGRgbjx4+nqqrqPPy0RCSe7GxvuLN1fr5YQ53JLoAfuWeaOHEiWVlZbNmyhQEDBrB6eIjG\nIgAAB9VJREFU9WqOHTtGZWUlzzzzDG+88QYAmzdvBuD48eMcP36ca665Bucc8+fP5+DBg+zZs4cv\nv/yyaXizT58+zJo1i+eff76prjVr1jBmzBiys7MB4tbXEZGh0JqaGvLz83n44Yc5evQoZWVlzJw5\nkyNHjpyPH5GIxNCvn5cSac2aluc11Cnd3qWXXkptbS2TJ09m7NixAGRnZzNnzpwzek7RQ52jRo0i\nLy+PXr16MWjQIO69994W5UtKSnjllVf45ptvAFi9ejUlJSVN1ztSX0e88MIL3HTTTUybNg2AvLw8\nrrrqKtatW9fpZ4lI59x9t5djMJqGOqUFs/PzOp9qamoIhUJs376dqVOnMmTIENLT01m+fDmHDx+O\ned+hQ4coKCggKyuL9PR0CgsLW5TPyckhMzOT119/nX379rFjxw7mzp3bdL2z9cVSXV3Nyy+/TCgU\nIhQKkZGRwTvvvMOBAwc6/SwR6ZwpU7weX21t8zkFPmnBufPzOl927NjB/v37yc3NZe7cucyYMYOa\nmhrq6uq46667mnp4bc2wnD9/PikpKXz66afU1dVRXl5+xuSXoqIiVq1aRXl5OdOmTSMzM7PpWrz6\nWuvfvz8no5J5HTx4sOn4sssuo7i4mNraWmprazl69Cj19fU88MAD5/SzEZH2jRrlJcx9993mc42N\n+o5PuqH6+nrWrl1LQUEBRUVFjB07lhMnTpCRkcHFF1/M9u3beTFqq/fMzExSUlL47LPPWjxjwIAB\npKamUlNTwxNPPHFGPcXFxWzYsIEVK1a0GOYE4tYHLYdVx40bx0svvURDQwPvv/8+r776atO1wsJC\n3nzzTdavX09jYyOnTp2iqqqK/fv3n/PPSUTiM/OCXH5+8zn1+KRbmT59OmlpaQwfPpylS5dy//33\ns3LlSgCefvppFi5cSFpaGo899hizZ89uuq9v374sWLCAnJycpmHRRx55hA8++ID09HSmT5/OzJkz\nz6gvHA5z7bXXcvLkSW6++eYW1+LVBy17mYsXL2bv3r2EQiFKS0u55ZZbmq5lZWVRUVHBkiVLyMzM\nJBwOU1ZWpsXvIl3ktddavg9q4LNkz1BgZq6tz9iZtW6SOPo9iZw/keULL74IBQVexvjs7LYzx/t/\ne0kZFtXjExEJiEjvrqzM+7ehIfm3J2uLAp+ISIAcOACffw4PPggffQSDBiW6RV0vsIloRUSC6JJL\nYNIkePxx7/3QoYltTyKoxyciEjDRG1aPGZO4diSKenwiIgFz3XWwaRN8+CEMHpzo1nQ9zeqUbk2/\nJ5HE0KxOERGRJBHYoc5wOKwEqj1AOBxOdBNEJMkEdqhTRERi01CniIhIklDgExGRQFHgExGRQFHg\nExGRQAnErE7N3hQRkYikn9UpIiISTUOdIiISKAp8IiISKD0+8JnZAjPbZWYfmdlOM5uY6DaJiEj3\n1aMnt5jZJOBGYJxzrsHMQkDvBDdLRES6sZ7e4xsGHHbONQA452qdcwfNbIKZbTKzHWb2FzMbCmBm\nG83sSTP70Mw+Vu9QRCR4enrgWw8MN7N/mtnvzWyymfUCfgvMdM5NBJ4DlkTd09c5Nx74BbCy65ss\nIiKJ1KOHOp1zX5nZBOCHwFTgJeDXQDbwlnkL+FKA/VG3/cm/d4uZpZrZQOfc8S5uuoiIJEiPDnwA\nfuqFzcBmM/sErye3yzmXE+uWqGNr9V5ERJJcjx7qNLPvmdl3o06NA3YDmf7EF8ysl5ldEVVmtn8+\nF6hzztV3WYNFRCThenqPbwDwWzNLAxqAvcCdwLNR5y8CnsQLiACnzGwn3me/reubLCIiiRSoLcvM\nbCNwn3NuZ6LbIiIiidGjhzrPQnCivIiItClQPT4REZGg9fhERCTgFPhERCRQFPhERCRQFPhERCRQ\nFPhE2mBmp/00V7v8Tc1/5W+BF++esJkVdKKOdWb2d//5/zKzOr/OnWY2ycyeNbPLz/3TiEi0nr6A\nXeRC+co5NwHAzAbj7fE6EFgU556RwFy/bFxm1gcIOeciOwxNwVtjenNUsffOrukiEo96fCLtcM4d\nxtsR6G5o6tltNrP3/dckv+hSINfvsd1jZilm9riZbTOzf5jZz6Ie+yNgU7x6/TRakeBb7z9rl5mt\nN7OJ/vW9Zpbvl4lXn4j4FPhEOsA59zmQYmaZwH+A65xzVwFz8NJgATwEbHHOTXDOPQXcgbcf7DXA\n1cCdZhb2y94A/LUTTegPbHDOZQMngMVAHvBT/5h26hMRn4Y6RTou8h1fb+B3ZjYOOA2MjlH+euD7\nZjbLfz/QL1sN5AD3daLur51z6/3jT4BTzrlGPyNJJLjFq09EfAp8Ih1gZt8BGpxz/zWzR4CDzrkf\nmNlFwP9i3Qb80jn3VqtnjQT+7Zxr6EQTvo06bgS+Bi8tl598OWZ9ItKShjpF2tY0g9Mf3vwDzUOa\nacAB/7gYLwMIQD2QGvWMvwE/jwQmMxttZv3o/DBni/bEudZWfX07WY9I0lOPT6Rtffz0Vb3xelvP\nO+d+4197GvizmRXjBbCv/PMfA41m9iHwR+fcU2Y2AtjpL4U4BPwE+DH+RJl2uBjHscqtAFrXN6MD\n9YgEijapFulCZtYb2OqcuzrRbREJKgU+EREJFH3HJyIigaLAJyIigaLAJyIigaLAJyIigaLAJyIi\ngaLAJyIigaLAJyIigfJ/T45AWRDJ7PAAAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Get the values for a particular TimeSeriesResult\n", "print \"\\n-------- Example of Retrieving Time Series Result Values ---------\"\n", "\n", - "tsValues = read.getTimeSeriesResultValuesByResultId(1) # Return type is a pandas dataframe\n", "\n", + "tsValues = read.getResultValues(resultid =1) # Return type is a pandas dataframe\n", "# Print a few Time Series Values to the console\n", "try:\n", " print tsValues.head()\n", @@ -441,9 +248,9 @@ " fig = plt.figure()\n", " ax = fig.add_subplot(111)\n", " tsValues.plot(x='ValueDateTime', y='DataValue', kind='line',\n", - " title=tsResult.ResultObj.VariableObj.VariableNameCV + \" at \" + tsResult.ResultObj.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName,\n", + " title=tsResult.VariableObj.VariableNameCV + \" at \" + tsResult.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName,\n", " ax=ax)\n", - " ax.set_ylabel(tsResult.ResultObj.VariableObj.VariableNameCV + \" (\" + tsResult.ResultObj.UnitsObj.UnitsAbbreviation + \")\")\n", + " ax.set_ylabel(tsResult.VariableObj.VariableNameCV + \" (\" + tsResult.UnitsObj.UnitsAbbreviation + \")\")\n", " ax.set_xlabel(\"Date/Time\")\n", " ax.xaxis.set_minor_locator(dates.MonthLocator())\n", " ax.xaxis.set_minor_formatter(dates.DateFormatter('%b'))\n", @@ -452,18 +259,17 @@ " ax.grid(True)\n", " plt.show()\n", "except Exception as e:\n", - " print \"Unable to demo plotting of tsValues: \", e\n", - "\n" + " print \"Unable to demo plotting of tsValues: \", e" ] }, { "cell_type": "code", "execution_count": null, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], - "source": [] + "source": [ + "" + ] } ], "metadata": { @@ -475,7 +281,7 @@ "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 2.0 }, "file_extension": ".py", "mimetype": "text/x-python", @@ -487,4 +293,4 @@ }, "nbformat": 4, "nbformat_minor": 0 -} +} \ No newline at end of file diff --git a/Examples/Sample 1.1.py b/Examples/Sample 1.1.py index 54404ae..03b986e 100644 --- a/Examples/Sample 1.1.py +++ b/Examples/Sample 1.1.py @@ -1,10 +1,13 @@ -__author__ = 'stephanie' +from __future__ import (absolute_import, division, print_function) + import sys import os from odm2api.ODMconnection import dbconnection import pprint from odm2api.ODM1_1_1.services import SeriesService +__author__ = 'stephanie' + this_file = os.path.realpath(__file__) directory = os.path.dirname(this_file) sys.path.insert(0, directory) @@ -16,7 +19,7 @@ #connection to the ODM1 database dbconnection.createConnection('mysql', 'jws.uwrl.usu.edu', 'odm', "ODM", "ODM123!!", 1.1), #connection to the ODM2 database - dbconnection.createConnection('mysql', 'jws.uwrl.usu.edu', 'odm2', 'ODM', 'ODM123!!', 2.0)] + dbconnection.createConnection('mssql', '(local)', 'odm2', 'ODM', 'odm', 2.0)] for conn in conns: @@ -29,7 +32,7 @@ print odm1service = SeriesService(conn) - odm1service.refreshDB(conn.version) + pp.pprint(conn) print @@ -92,6 +95,3 @@ pp.pprint(odm1service.get_values_by_series(ser[0].id)) print "The end" - - - diff --git a/Examples/Sample.py b/Examples/Sample.py index bd941cd..dcd8896 100644 --- a/Examples/Sample.py +++ b/Examples/Sample.py @@ -1,44 +1,49 @@ +from __future__ import (absolute_import, division, print_function) + __author__ = 'stephanie' -import sys -import os +#import matplotlib.pyplot as plt -import matplotlib.pyplot as plt -from matplotlib import dates -#this will be removed when we can installthe api -# this_file = os.path.realpath(__file__) -# directory = os.path.dirname(os.path.dirname(this_file)) -# print directory -# sys.path.insert(0, directory) from odm2api.ODMconnection import dbconnection from odm2api.ODM2.services.readService import * +from odm2api.ODM2.services import CreateODM2 # Create a connection to the ODM2 database # ---------------------------------------- #connect to database -#createconnection (dbtype, servername, dbname, username, password) -#session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm') -#session_factory = dbconnection.createConnection('connection type: sqlite|mysql|mssql|postgresql', '/your/path/to/db/goes/here', 2.0) -session_factory = dbconnection.createConnection('sqlite', '/Users/denversmith/Downloads/ODM2.sqlite', 2.0) -# session_factory= dbconnection.createConnection('mssql') +# createconnection (dbtype, servername, dbname, username, password) +# session_factory = dbconnection.createConnection('connection type: sqlite|mysql|mssql|postgresql', '/your/path/to/db/goes/here', 2.0)#sqlite +session_factory = dbconnection.createConnection('postgresql', 'localhost', 'odm2', 'ODM', 'odm') +# session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm')#mysql + +# session_factory= dbconnection.createConnection('mssql', "(local)", "ODM2", "ODM", "odm")#win MSSQL + +# session_factory= dbconnection.createConnection('mssql', "arroyoodm2", "", "ODM", "odm")#mac/linux MSSQL +# session_factory = dbconnection.createConnection('sqlite', '/Users/stephanie/DEV/YODA-Tools/tests/test_files/XL_specimen.sqlite', 2.0) + + + + -#_session = session_factory.getSession() -read = ReadODM2(session_factory) +#_session = session_factory.getSession() +read = ReadODM2(session_factory) +create = CreateODM2(session_factory) + # Run some basic sample queries. # ------------------------------ # Get all of the variables from the database and print their names to the console allVars = read.getVariables() - +print ("\n-------- Information about Variables ---------") for x in allVars: print(x.VariableCode + ": " + x.VariableNameCV) @@ -46,13 +51,13 @@ # Get all of the people from the database allPeople = read.getPeople() - +print ("\n-------- Information about People ---------") for x in allPeople: print(x.PersonFirstName + " " + x.PersonLastName) try: print("\n-------- Information about an Affiliation ---------") - allaff = read.getAllAffiliations() + allaff = read.getAffiliations() for x in allaff: print(x.PersonObj.PersonFirstName + ": " + str(x.OrganizationID)) except Exception as e: @@ -60,18 +65,20 @@ # Get all of the SamplingFeatures from the database that are Sites try: - siteFeatures = read.getSamplingFeaturesByType('Site') + print ("\n-------- Information about Sites ---------") + siteFeatures = read.getSamplingFeatures(type= 'site') + # siteFeatures = read.getSamplingFeatures(type='Site') numSites = len(siteFeatures) - + print ("Successful query") for x in siteFeatures: - print(x.SamplingFeatureCode + ": " + x.SamplingFeatureName) + print(x.SamplingFeatureCode + ": " + x.SamplingFeatureTypeCV ) except Exception as e: print("Unable to demo getSamplingFeaturesByType", e) # Now get the SamplingFeature object for a SamplingFeature code try: - sf = read.getSamplingFeatureByCode('USU-LBR-Mendon') + sf = read.getSamplingFeatures(codes=['USU-LBR-Mendon'])[0] print(sf) print("\n-------- Information about an individual SamplingFeature ---------") print("The following are some of the attributes of a SamplingFeature retrieved using getSamplingFeatureByCode(): \n") @@ -87,20 +94,16 @@ #add sampling feature print("\n------------ Create Sampling Feature --------- \n") try: - from odm2api.ODM2.models import SamplingFeatures - newsf = SamplingFeatures() + # from odm2api.ODM2.models import SamplingFeatures session = session_factory.getSession() - newsf.FeatureGeometry = "POINT(-111.946 41.718)" - newsf.Elevation_m=100 - newsf.ElevationDatumCV=sf.ElevationDatumCV - newsf.SamplingFeatureCode= "TestSF" - newsf.SamplingFeatureDescription = "this is a test to add Feature Geomotry" - newsf.SamplingFeatureGeotypeCV= "Point" - newsf.SamplingFeatureTypeCV=sf.SamplingFeatureTypeCV - newsf.SamplingFeatureUUID= sf.SamplingFeatureUUID+"2" - session.add(newsf) + newsf = Sites(FeatureGeometryWKT = "POINT(-111.946 41.718)", Elevation_m=100, ElevationDatumCV=sf.ElevationDatumCV, + SamplingFeatureCode= "TestSF",SamplingFeatureDescription = "this is a test in sample.py", + SamplingFeatureGeotypeCV= "Point", SamplingFeatureTypeCV=sf.SamplingFeatureTypeCV,SamplingFeatureUUID= sf.SamplingFeatureUUID+"2", + SiteTypeCV="cave", Latitude= "100", Longitude= "-100", SpatialReferenceID= 0) + + c=create.createSamplingFeature(newsf) #session.commit() - print("new sampling feature added to database", newsf) + print("new sampling feature added to database", c) except Exception as e : print("error adding a sampling feature: " + str(e)) @@ -125,29 +128,29 @@ # Now get a particular Result using a ResultID -print("\n------- Example of Retrieving Attributes of a Time Series Result -------") +print("\n------- Example of Retrieving Attributes of a Result -------") try: - tsResult = read.getTimeSeriesResultByResultId(1) + tsResult = read.getResults(ids = [1])[0] print ( - "The following are some of the attributes for the TimeSeriesResult retrieved using getTimeSeriesResultByResultID(): \n" + - "ResultTypeCV: " + tsResult.ResultObj.ResultTypeCV + "\n" + + "The following are some of the attributes for the TimeSeriesResult retrieved using getResults(ids=[1]): \n" + + "ResultTypeCV: " + tsResult.ResultTypeCV + "\n" + # Get the ProcessingLevel from the TimeSeriesResult's ProcessingLevel object - "ProcessingLevel: " + tsResult.ResultObj.ProcessingLevelObj.Definition + "\n" + - "SampledMedium: " + tsResult.ResultObj.SampledMediumCV + "\n" + + "ProcessingLevel: " + tsResult.ProcessingLevelObj.Definition + "\n" + + "SampledMedium: " + tsResult.SampledMediumCV + "\n" + # Get the variable information from the TimeSeriesResult's Variable object - "Variable: " + tsResult.ResultObj.VariableObj.VariableCode + ": " + tsResult.ResultObj.VariableObj.VariableNameCV + "\n" - "AggregationStatistic: " + tsResult.AggregationStatisticCV + "\n" + - "Elevation_m: " + str(sf.Elevation_m) + "\n" + + "Variable: " + tsResult.VariableObj.VariableCode + ": " + tsResult.VariableObj.VariableNameCV + "\n" + #"AggregationStatistic: " + tsResult.AggregationStatisticCV + "\n" + + # Get the site information by drilling down - "SamplingFeature: " + tsResult.ResultObj.FeatureActionObj.SamplingFeatureObj.SamplingFeatureCode + " - " + - tsResult.ResultObj.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName) + "SamplingFeature: " + tsResult.FeatureActionObj.SamplingFeatureObj.SamplingFeatureCode + " - " + + tsResult.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName) except Exception as e: print("Unable to demo Example of retrieving Attributes of a time Series Result: ", e) # Get the values for a particular TimeSeriesResult print("\n-------- Example of Retrieving Time Series Result Values ---------") -tsValues = read.getTimeSeriesResultValuesByResultId(1) # Return type is a pandas dataframe +tsValues = read.getResultValues(resultid = 1) # Return type is a pandas datafram # Print a few Time Series Values to the console # tsValues.set_index('ValueDateTime', inplace=True) @@ -159,18 +162,9 @@ # Plot the time series try: - fig = plt.figure() - ax = fig.add_subplot(111) - tsValues.plot(x='ValueDateTime', y='DataValue', kind='line', - title=tsResult.ResultObj.VariableObj.VariableNameCV + " at " + tsResult.ResultObj.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName, - ax=ax) - ax.set_ylabel(tsResult.ResultObj.VariableObj.VariableNameCV + " (" + tsResult.ResultObj.UnitsObj.UnitsAbbreviation + ")") - ax.set_xlabel("Date/Time") - ax.xaxis.set_minor_locator(dates.MonthLocator()) - ax.xaxis.set_minor_formatter(dates.DateFormatter('%b')) - ax.xaxis.set_major_locator(dates.YearLocator()) - ax.xaxis.set_major_formatter(dates.DateFormatter('\n%Y')) - ax.grid(True) + plt.figure() + ax=tsValues.plot(x='ValueDateTime', y='DataValue') + plt.show() except Exception as e: print("Unable to demo plotting of tsValues: ", e) diff --git a/Forms/clsDBConfig.py b/Forms/clsDBConfig.py index d92e1aa..93556b8 100644 --- a/Forms/clsDBConfig.py +++ b/Forms/clsDBConfig.py @@ -1,4 +1,5 @@ -# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- +from __future__ import (absolute_import, division, print_function) ########################################################################### ## Python code generated with wxFormBuilder (version Jun 5 2014) @@ -10,124 +11,128 @@ import wx import wx.xrc + ########################################################################### ## Class clsDBConfiguration ########################################################################### -class clsDBConfiguration ( wx.Panel ): - - def __init__( self, parent ): - wx.Panel.__init__ ( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.Size( 500,291 ), style = wx.SIMPLE_BORDER|wx.TAB_TRAVERSAL ) - - self.SetMinSize( wx.Size( 442,291 ) ) - self.SetMaxSize( wx.Size( 627,291 ) ) - - formSizer = wx.BoxSizer( wx.VERTICAL ) - - sbSizer = wx.StaticBoxSizer( wx.StaticBox( self, wx.ID_ANY, u"Database Connection" ), wx.VERTICAL ) - - connectionSizer = wx.FlexGridSizer( 0, 2, 0, 15 ) - connectionSizer.AddGrowableCol( 1 ) - connectionSizer.SetFlexibleDirection( wx.VERTICAL ) - connectionSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_ALL ) - - self.stVersion = wx.StaticText( self, wx.ID_ANY, u"DB Version:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT ) - self.stVersion.Wrap( -1 ) - connectionSizer.Add( self.stVersion, 0, wx.ALL|wx.ALIGN_RIGHT|wx.EXPAND, 5 ) - - cbDatabaseType1Choices = [ u"2.0", u"1.1.1" ] - self.cbDatabaseType1 = wx.ComboBox( self, wx.ID_ANY, u"2.0", wx.DefaultPosition, wx.DefaultSize, cbDatabaseType1Choices, wx.CB_READONLY|wx.CB_SORT ) - self.cbDatabaseType1.SetSelection( 1 ) - connectionSizer.Add( self.cbDatabaseType1, 1, wx.ALL|wx.EXPAND, 5 ) - - self.stConnType = wx.StaticText( self, wx.ID_ANY, u"Connection Type:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT ) - self.stConnType.Wrap( -1 ) - connectionSizer.Add( self.stConnType, 0, wx.ALL|wx.EXPAND|wx.ALIGN_RIGHT, 5 ) - - cbDatabaseTypeChoices = [] - self.cbDatabaseType = wx.ComboBox( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, cbDatabaseTypeChoices, wx.CB_READONLY|wx.CB_SORT ) - connectionSizer.Add( self.cbDatabaseType, 1, wx.ALL|wx.EXPAND, 5 ) - - self.stServer = wx.StaticText( self, wx.ID_ANY, u"Server:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT ) - self.stServer.Wrap( -1 ) - connectionSizer.Add( self.stServer, 0, wx.ALL|wx.EXPAND|wx.ALIGN_RIGHT, 5 ) - - self.txtServer = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0|wx.FULL_REPAINT_ON_RESIZE|wx.SIMPLE_BORDER ) - connectionSizer.Add( self.txtServer, 1, wx.ALL|wx.EXPAND, 5 ) - - self.stDBName = wx.StaticText( self, wx.ID_ANY, u"Database:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT ) - self.stDBName.Wrap( -1 ) - self.stDBName.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString ) ) - - connectionSizer.Add( self.stDBName, 0, wx.ALL|wx.EXPAND|wx.ALIGN_RIGHT, 5 ) - - self.txtDBName = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0|wx.SIMPLE_BORDER ) - connectionSizer.Add( self.txtDBName, 1, wx.ALL|wx.EXPAND, 5 ) - - self.stUser = wx.StaticText( self, wx.ID_ANY, u"User:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT ) - self.stUser.Wrap( -1 ) - self.stUser.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString ) ) - - connectionSizer.Add( self.stUser, 0, wx.ALL|wx.EXPAND|wx.ALIGN_RIGHT, 5 ) - - self.txtUser = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0|wx.SIMPLE_BORDER ) - connectionSizer.Add( self.txtUser, 1, wx.ALL|wx.EXPAND, 5 ) - - self.stPass = wx.StaticText( self, wx.ID_ANY, u"Password:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT ) - self.stPass.Wrap( -1 ) - self.stPass.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString ) ) - - connectionSizer.Add( self.stPass, 0, wx.ALL|wx.EXPAND|wx.ALIGN_RIGHT, 5 ) - - self.txtPass = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_PASSWORD|wx.SIMPLE_BORDER ) - connectionSizer.Add( self.txtPass, 1, wx.ALL|wx.EXPAND, 5 ) - - - sbSizer.Add( connectionSizer, 90, wx.EXPAND, 3 ) - - - formSizer.Add( sbSizer, 1, wx.ALL|wx.EXPAND, 7 ) - - btnSizer = wx.FlexGridSizer( 0, 3, 0, 25 ) - btnSizer.AddGrowableCol( 0 ) - btnSizer.AddGrowableCol( 1 ) - btnSizer.AddGrowableCol( 2 ) - btnSizer.SetFlexibleDirection( wx.VERTICAL ) - btnSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_ALL ) - - self.btnTest = wx.Button( self, wx.ID_ANY, u"Test Connection", wx.DefaultPosition, wx.DefaultSize, 0 ) - btnSizer.Add( self.btnTest, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.btnSave = wx.Button( self, wx.ID_ANY, u"Save Connection", wx.DefaultPosition, wx.DefaultSize, 0 ) - btnSizer.Add( self.btnSave, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - self.btnCancel = wx.Button( self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0 ) - btnSizer.Add( self.btnCancel, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) - - - formSizer.Add( btnSizer, 10, wx.EXPAND, 2 ) - - - self.SetSizer( formSizer ) - self.Layout() - - # Connect Events - self.btnTest.Bind( wx.EVT_BUTTON, self.OnBtnTest ) - self.btnSave.Bind( wx.EVT_BUTTON, self.OnBtnSave ) - self.btnCancel.Bind( wx.EVT_BUTTON, self.OnBtnCancel ) - - def __del__( self ): - pass - - - # Virtual event handlers, overide them in your derived class - def OnBtnTest( self, event ): - event.Skip() - - def OnBtnSave( self, event ): - event.Skip() - - def OnBtnCancel( self, event ): - event.Skip() - +class clsDBConfiguration(wx.Panel): + def __init__(self, parent): + wx.Panel.__init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size(500, 291), + style=wx.SIMPLE_BORDER | wx.TAB_TRAVERSAL) + + self.SetMinSize(wx.Size(442, 291)) + self.SetMaxSize(wx.Size(627, 291)) + + formSizer = wx.BoxSizer(wx.VERTICAL) + + sbSizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, u"Database Connection"), wx.VERTICAL) + + connectionSizer = wx.FlexGridSizer(0, 2, 0, 15) + connectionSizer.AddGrowableCol(1) + connectionSizer.SetFlexibleDirection(wx.VERTICAL) + connectionSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_ALL) + + self.stVersion = wx.StaticText(self, wx.ID_ANY, u"DB Version:", wx.DefaultPosition, wx.DefaultSize, + wx.ALIGN_RIGHT) + self.stVersion.Wrap(-1) + connectionSizer.Add(self.stVersion, 0, wx.ALL | wx.ALIGN_RIGHT | wx.EXPAND, 5) + + cbDatabaseType1Choices = [u"2.0"]#, u"1.1.1"] + self.cbDatabaseType1 = wx.ComboBox(self, wx.ID_ANY, u"2.0", wx.DefaultPosition, wx.DefaultSize, + cbDatabaseType1Choices, wx.CB_READONLY | wx.CB_SORT) + self.cbDatabaseType1.SetSelection(1) + connectionSizer.Add(self.cbDatabaseType1, 1, wx.ALL | wx.EXPAND, 5) + + self.stConnType = wx.StaticText(self, wx.ID_ANY, u"Connection Type:", wx.DefaultPosition, wx.DefaultSize, + wx.ALIGN_RIGHT) + self.stConnType.Wrap(-1) + connectionSizer.Add(self.stConnType, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) + + cbDatabaseTypeChoices = [] + self.cbDatabaseType = wx.ComboBox(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, + cbDatabaseTypeChoices, wx.CB_READONLY | wx.CB_SORT) + connectionSizer.Add(self.cbDatabaseType, 1, wx.ALL | wx.EXPAND, 5) + + self.stServer = wx.StaticText(self, wx.ID_ANY, u"Server:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) + self.stServer.Wrap(-1) + connectionSizer.Add(self.stServer, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) + + self.txtServer = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, + 0 | wx.FULL_REPAINT_ON_RESIZE | wx.SIMPLE_BORDER) + connectionSizer.Add(self.txtServer, 1, wx.ALL | wx.EXPAND, 5) + + self.stDBName = wx.StaticText(self, wx.ID_ANY, u"Database:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) + self.stDBName.Wrap(-1) + self.stDBName.SetFont(wx.Font(wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString)) + + connectionSizer.Add(self.stDBName, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) + + self.txtDBName = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, + 0 | wx.SIMPLE_BORDER) + connectionSizer.Add(self.txtDBName, 1, wx.ALL | wx.EXPAND, 5) + + self.stUser = wx.StaticText(self, wx.ID_ANY, u"User:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) + self.stUser.Wrap(-1) + self.stUser.SetFont(wx.Font(wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString)) + + connectionSizer.Add(self.stUser, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) + + self.txtUser = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, + 0 | wx.SIMPLE_BORDER) + connectionSizer.Add(self.txtUser, 1, wx.ALL | wx.EXPAND, 5) + + self.stPass = wx.StaticText(self, wx.ID_ANY, u"Password:", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT) + self.stPass.Wrap(-1) + self.stPass.SetFont(wx.Font(wx.NORMAL_FONT.GetPointSize(), 70, 90, 90, False, wx.EmptyString)) + + connectionSizer.Add(self.stPass, 0, wx.ALL | wx.EXPAND | wx.ALIGN_RIGHT, 5) + + self.txtPass = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, + wx.TE_PASSWORD | wx.SIMPLE_BORDER) + connectionSizer.Add(self.txtPass, 1, wx.ALL | wx.EXPAND, 5) + + sbSizer.Add(connectionSizer, 90, wx.EXPAND, 3) + + formSizer.Add(sbSizer, 1, wx.ALL | wx.EXPAND, 7) + + btnSizer = wx.FlexGridSizer(0, 3, 0, 25) + btnSizer.AddGrowableCol(0) + btnSizer.AddGrowableCol(1) + btnSizer.AddGrowableCol(2) + btnSizer.SetFlexibleDirection(wx.VERTICAL) + btnSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_ALL) + + self.btnTest = wx.Button(self, wx.ID_ANY, u"Test Connection", wx.DefaultPosition, wx.DefaultSize, 0) + btnSizer.Add(self.btnTest, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL, 5) + + self.btnSave = wx.Button(self, wx.ID_ANY, u"Save Connection", wx.DefaultPosition, wx.DefaultSize, 0) + btnSizer.Add(self.btnSave, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL, 5) + + self.btnCancel = wx.Button(self, wx.ID_ANY, u"Cancel", wx.DefaultPosition, wx.DefaultSize, 0) + btnSizer.Add(self.btnCancel, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL, 5) + + formSizer.Add(btnSizer, 10, wx.EXPAND, 2) + + self.SetSizer(formSizer) + self.Layout() + + # Connect Events + self.btnTest.Bind(wx.EVT_BUTTON, self.OnBtnTest) + self.btnSave.Bind(wx.EVT_BUTTON, self.OnBtnSave) + self.btnCancel.Bind(wx.EVT_BUTTON, self.OnBtnCancel) + + self.btnTest.SetFocus() + + def __del__(self): + pass + + # Virtual event handlers, overide them in your derived class + def OnBtnTest(self, event): + event.Skip() + + def OnBtnSave(self, event): + event.Skip() + def OnBtnCancel(self, event): + event.Skip() diff --git a/Forms/frmDBConfig.py b/Forms/frmDBConfig.py index 973562a..133eb50 100644 --- a/Forms/frmDBConfig.py +++ b/Forms/frmDBConfig.py @@ -1,3 +1,5 @@ +from __future__ import (absolute_import, division, print_function) + """Subclass of clsDBConfiguration, which is generated by wxFormBuilder.""" import wx @@ -55,7 +57,7 @@ def OnBtnTest(self, event): def OnBtnSave(self, event): - + self.parent.EndModal(wx.ID_OK) @@ -78,6 +80,7 @@ def validateInput(self, conn_dict): if self.service_manager.test_connection(conn_dict): message = "This connection is valid" wx.MessageBox(message, 'Test Connection', wx.OK) + self.btn else: #TODO add error message if user cannont connect to the database ( not using VPN) but the db is still 1.1.1) if not (self.service_manager.get_db_version(conn_dict)): diff --git a/MANIFEST.in b/MANIFEST.in index 2a0b65c..96d5afd 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,5 @@ include README.md include *.txt +include versioneer.py +include odm2api/_version.py diff --git a/README.md b/README.md index 389acf1..19ec59c 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,95 @@ ODM2 Python API -==== +=============== -A Python-based application programmer's interface for the Observations Data Model 2 (ODM2) +[![Build Status](https://travis-ci.org/ODM2/ODM2PythonAPI.svg?branch=master)](https://travis-ci.org/ODM2/ODM2PythonAPI) +[![Build status](https://ci.appveyor.com/api/projects/status/c13bxn6xvgv5kglt?svg=true)](https://ci.appveyor.com/project/odm2bot/odm2pythonapi) + + +A Python-based application programmer's interface for the +[Observations Data Model 2 (ODM2)](http://odm2.org). [List of current and planned functions included in the API](https://github.com/ODM2/ODM2PythonAPI/blob/master/doc/APIFunctionList.md) -### Installation +## Documentation + +For the latest documentation of the ODM2 Python API, see [http://odm2.github.io/ODM2PythonAPI/](http://odm2.github.io/ODM2PythonAPI/) + +## Installation + +The easiest and most reliable way to install the ODM2 Python API (`odm2api`) is using the +[Conda package management system](http://conda.pydata.org/docs/) +via either +[Anaconda](https://www.continuum.io/downloads) +or +[Miniconda](http://conda.pydata.org/miniconda.html). +To start using conda (if it's not your system default), +add conda to the PATH; on MacOSX and Linux, +it's something like `export PATH=$HOME/miniconda/bin:$PATH`, +but the exact path may vary. + +To activate a conda environment, say, "myenv": + +```bash +activate myenv # On Windows +source activate myenv # On MacOSX or Linux +``` + +**Note:** `odm2api` currently is only tested on Python 2.7. Some changes have been made to support Python 3.x, +but they haven't been tested thoroughly. + + +### Latest release, from ODM2 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) +for all major OS paltforms (linux, OSX, win32/win64). +To install it on an existing conda environment: + +``` +conda install -c odm2 odm2api +``` + +All dependencies are installed, +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 +``` + +### 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: -Currently the easiest and most reliable way to install the ODM2 Python API (`odm2api`) is using the [Conda package management system](http://conda.pydata.org/docs/) via either [Anaconda](https://www.continuum.io/downloads) or [Miniconda](http://conda.pydata.org/miniconda.html). To create a new `odm2api` environment, first download the conda environment file [condaenvironment_1.yml](https://raw.githubusercontent.com/ODM2/ODM2PythonAPI/master/condaenvironment_1.yml). Then, on a terminal shell: +```bash +conda env create -n myenv --file py2_conda_environment.yml +``` -1. Add conda to the PATH; on MacOSX and Linux, it's something like `export PATH=$HOME/miniconda/bin:$PATH`, but the exact path may vary. -2. Go to the directory where `condaenvironment_1.yml` was downloaded. -3. Create a new conda environment. This command will create an environment called 'odm2api_env1': +Activate the new environment, then install `odm2api` into the environment: - ```bash - conda env create -f condaenvironment_1.yml - ``` -4. Activate the new environment: +```bash +activate myenv # On Windows +source activate myenv # On MacOSX or Linux - ```bash - activate odm2api_env1 # On Windows - source activate odm2api_env1 # On MacOSX or Linux - ``` -5. Install the `odm2api` package into the environment: +pip install --process-dependency-links git+https://github.com/ODM2/ODM2PythonAPI.git +``` - ```bash - pip install --process-dependency-links git+https://github.com/ODM2/ODM2PythonAPI.git - ``` - -### Credits +## Credits -This work was supported by National Science Foundation Grants [EAR-1224638](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1224638) and [ACI-1339834](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1339834). Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation. +This work was supported by National Science Foundation Grants +[EAR-1224638](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1224638) +and +[ACI-1339834](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1339834). +Any opinions, findings, +and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation. diff --git a/appveyor.yml b/appveyor.yml index 9bf8ad1..b34a56c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,44 +4,56 @@ environment: # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the # /E:ON and /V:ON options are not enabled in the batch script intepreter # See: http://stackoverflow.com/a/13751649/163740 - CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" + PYTHON: "C:\\conda" + MINICONDA_VERSION: "latest" + # CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" + CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\ci-helpers/appveyor/windows_sdk.cmd" + CONDA_CHANNELS: "odm2" + CONDA_DEPENDENCIES: "scipy pandas seaborn sqlalchemy pymysql geoalchemy-odm2 shapely psycopg2" + PIP_DEPENDENCIES: "pyodbc,pytest" + #,-e git+https://github.com/ODM2/geoalchemy.git@v0.7.4#egg=geoalchemy-0.7.4" + # postgres POSTGRES_PORT: tcp://localhost:5432 POSTGRES_ENV_POSTGRES_USER: postgres POSTGRES_ENV_POSTGRES_PASSWORD: Password12! POSTGRES_ENV_POSTGRES_DB: odm2 - POSTGRES_PATH: C:\Program Files\PostgreSQL\9.4 + POSTGRES_PATH: C:\Program Files\PostgreSQL\9.5 PGUSER: postgres PGPASSWORD: Password12! + # mysql MYSQL_PORT: tcp://localhost:3306 MYSQL_ENV_MYSQL_USER: root MYSQL_ENV_MYSQL_PASSWORD: Password12! MYSQL_ENV_MYSQL_DATABASE: odm2 - MYSQL_PATH: C:\Program Files\MySql\MySQL Server 5.6 + MYSQL_PATH: C:\Program Files\MySql\MySQL Server 5.7 MYSQL_PWD: Password12! + # sql server SQLSERVER_ENV_SQLSERVER_HOST: localhost SQLSERVER_ENV_SQLSERVER_PORT: 1433 SQLSERVER_ENV_SQLSERVER_USER: sa SQLSERVER_ENV_SQLSERVER_PASSWORD: Password12! SQLSERVER_ENV_SQLSERVER_DATABASE: odm2 - matrix: + # Pre-installed Python versions, which Appveyor may upgrade to # a later point release. # See: http://www.appveyor.com/docs/installed-software#python + matrix: + - PYTHON: "C:\\Python27-conda32" + PYTHON_VERSION: "2.7" + PYTHON_ARCH: "32" + - matrix: - - PYTHON: "C:\\Python27-conda32" - PYTHON_VERSION: "2.7" - PYTHON_ARCH: "32" + - PYTHON: "C:\\Python27-conda64" + PYTHON_VERSION: "2.7" + PYTHON_ARCH: "64" + NUMPY_VERSION: "stable" - - PYTHON: "C:\\Python34-conda64" - PYTHON_VERSION: "3.4" - PYTHON_ARCH: "64" services: - mssql2008r2sp2 @@ -66,106 +78,222 @@ install: # Install Python (from the official .msi of http://python.org) and pip when # not already installed. - - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } +# - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } + - ps: ci-helpers/appveyor/install-miniconda.ps1 + # Prepend newly installed Python to the PATH of this build (this cannot be # done from inside the powershell script as it would require to restart # the parent CMD process). - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" # add databases - - "SET PATH=%POSTGRES_PATH%\bin;%MYSQL_PATH%\bin;%PATH%" + - "SET PATH=%POSTGRES_PATH%\\bin;%MYSQL_PATH%\\bin;%PATH%" + - "activate test" # Check that we have the expected version and architecture for Python - "python --version" - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" - # Upgrade to the latest version of pip to avoid it displaying warnings - # about it being out of date. - - "pip install --disable-pip-version-check --user --upgrade pip" - # Install the build dependencies of the project. If some dependencies contain - # compiled extensions and are not provided as pre-built wheel packages, - # pip will build them from source using the MSVC compiler matching the - # target Python version and architecture - - "%CMD_IN_ENV% pip install -r dev-requirements.txt" build_script: - # Build the compiled extension - - "%CMD_IN_ENV% python setup.py build" -build_script: - # Build the compiled extension - - "%CMD_IN_ENV% python setup.py build" - build_script: +##https://github.com/sqlectron/sqlectron-core/blob/master/appveyor.yml + - echo %PATH% + # postgres - - createdb odm2 - - psql -d odm2 -a -f spec/databases/postgresql/schema/schema.sql + - sh ci-helpers\postgres_setup.sh +# - psql createdb marchantariats +# - psql -d marchantariats -a -f tests/usecasesql/marchantariats/marchantariats.sql + + # mysql - - mysql -e "drop database test; create database odm2;" --user=root - - mysql sqlectron < spec/databases/mysql/schema/schema.sql --user=root + - sh ci-helpers\mysql_setup.sh +# - mysql -e "drop database test; create database odm2;" --user=root +# - mysql odm2 < tests/usecasesql/littlebearriver/sampledatabases/odm2_mysql/LBR_MySQL_SmallExample.sql --user=root + # sqlserver - - ps: ./appveyor-sqlserver.ps1 SQL2008R2SP2 + - ps: ci-helpers\appveyor\sqlserver.ps1 SQL2008R2SP2 - sqlcmd -S localhost,1433 -U sa -P Password12! -Q "CREATE DATABASE odm2" -d "master" - - sqlcmd -S localhost,1433 -U sa -P Password12! -i spec/databases/sqlserver/schema/schema.sql -d "odm2" + - sqlcmd -S localhost,1433 -U sa -P Password12! -i tests/usecasesql/littlebearriver/sampledatabases/odm2_ms_sql_server/LBR_ODM2_MSSQLDump.sql -d "odm2" - sqlcmd -S localhost,1433 -U sa -P Password12! -Q "select table_name from information_schema.tables" -d "odm2" test_script: # Run the project tests - - "%CMD_IN_ENV% python setup.py nosetests" - -language: python -python: -# - "2.6" - - "2.7" -# - "3.2" -# - "3.3" -# - "3.4" -# - "3.5" -# - "3.5-dev" # 3.5 development branch -# - "nightly" # currently points to 3.6-dev -# command to install dependencies - -before_install: -#https://github.com/sqlectron/sqlectron-core/blob/master/appveyor.yml - - mysql -e "CREATE USER 'ODM'@'localhost' IDENTIFIED BY 'odm';GRANT ALL PRIVILEGES ON *.* TO 'ODM'@'localhost';" -uroot - - mysql -e "create database IF NOT EXISTS odm2;" -uroot - - mysql -e "create database IF NOT EXISTS odm2test;" -uroot - - psql -U postgres -c "create extension postgis" - - psql -c 'DROP DATABASE IF EXISTS odm2test;' -U postgres; - - psql -c 'create database odm2test;' -U postgres; -# - psql -U postgres -d odm2test -a -f ./tests/schemas/postgresql/ODM2_for_PostgreSQL.sql - - psql -c 'DROP DATABASE IF EXISTS odm2;' -U postgres; - - psql -c 'create database odm2;' -U postgres; - # patterned after: https://github.com/ptrv/gpx2spatialite/blob/master/.travis.yml -# - sudo apt-get install -y python-software-properties -# - sudo apt-add-repository -y ppa:git-core/ppa -# - sudo apt-add-repository -y ppa:ubuntugis/ppa -# - sudo apt-get update -qq -# - sudo apt-get install unixodbc unixodbc-dev tdsodbc -# - sudo apt-get install freetds-dev freetds-bin -# - sudo apt-get install libc6 e2fsprogs # mssql driver - # Spatialiate -# - sudo apt-get install -y libproj-dev libgeos-dev libspatialite-dev -# - sudo ln -s /usr/lib/x86_64-linux-gnu/libspatialite.so /usr/lib/libspatialite.so -# - sudo apt-get install python-scipy python-matplotlib python-pandas python-sympy python-nose -# - sudo apt-get install python-matplotlib python-pandas python-nose - - pip install pandas -install: # now just our code - - pip install git+https://github.com/ODM2/geoalchemy.git@odm2#egg=geoalchemy-0.7.3 - - pip install . - - pip install -r requirements_tests.txt --allow-external pyodbc --allow-unverified pyodbc - # pysqlite - - pip install pysqlite - - dir .\tests\usecasesql\littlebearriver\sampledatabases\odm2_mysql\LBR_MySQL_SmallExample.sql .\tests\usecasesql\marchantariats\marchantariats.sql - - mysql --user root --verbose odm2 < .\tests\usecasesql\littlebearriver\sampledatabases\odm2_mysql\LBR_MySQL_SmallExample.sql -# add -a to psql to see full log - - psql -U postgres -f ./tests/usecasesql/marchantariats/marchantariats.sql - -# don't forget to open up the azure mssql server to these addreses -# https://docs.travis-ci.com/user/ip-addresses/ - -# command to run tests -script: -# just the connection part - - py.test tests/test_connection.py - - py.test + - "py.test" + + + + + +#environment: +## patterned after: https://github.com/ogrisel/python-appveyor-demo/blob/master/appveyor.yml +# global: +# # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the +# # /E:ON and /V:ON options are not enabled in the batch script intepreter +# # See: http://stackoverflow.com/a/13751649/163740 +# CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" +# # postgres +# POSTGRES_PORT: tcp://localhost:5432 +# POSTGRES_ENV_POSTGRES_USER: postgres +# POSTGRES_ENV_POSTGRES_PASSWORD: Password12! +# POSTGRES_ENV_POSTGRES_DB: odm2 +# POSTGRES_PATH: C:\Program Files\PostgreSQL\9.4 +# PGUSER: postgres +# PGPASSWORD: Password12! +# # mysql +# MYSQL_PORT: tcp://localhost:3306 +# MYSQL_ENV_MYSQL_USER: root +# MYSQL_ENV_MYSQL_PASSWORD: Password12! +# MYSQL_ENV_MYSQL_DATABASE: odm2 +# MYSQL_PATH: C:\Program Files\MySql\MySQL Server 5.6 +# MYSQL_PWD: Password12! +# # sql server +# SQLSERVER_ENV_SQLSERVER_HOST: localhost +# SQLSERVER_ENV_SQLSERVER_PORT: 1433 +# SQLSERVER_ENV_SQLSERVER_USER: sa +# SQLSERVER_ENV_SQLSERVER_PASSWORD: Password12! +# SQLSERVER_ENV_SQLSERVER_DATABASE: odm2 +# matrix: +# +# +# # Pre-installed Python versions, which Appveyor may upgrade to +# # a later point release. +# # See: http://www.appveyor.com/docs/installed-software#python +# +# +# matrix: +# - PYTHON: "C:\\Python27-conda32" +# PYTHON_VERSION: "2.7" +# PYTHON_ARCH: "32" +# +# - PYTHON: "C:\\Python34-conda64" +# PYTHON_VERSION: "3.4" +# PYTHON_ARCH: "64" +# +#services: +# - mssql2008r2sp2 +# - mysql +# - postgresql +# +#install: +# # If there is a newer build queued for the same PR, cancel this one. +# # The AppVeyor 'rollout builds' option is supposed to serve the same +# # purpose but it is problematic because it tends to cancel builds pushed +# # directly to master instead of just PR builds (or the converse). +# # credits: JuliaLang developers. +# - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` +# https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` +# Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` +# throw "There are newer queued builds for this pull request, failing early." } +# - ECHO "Filesystem root:" +# - ps: "ls \"C:/\"" +# +# - ECHO "Installed SDKs:" +# - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\"" +# +# # Install Python (from the official .msi of http://python.org) and pip when +# # not already installed. +# - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } +# +# # Prepend newly installed Python to the PATH of this build (this cannot be +# # done from inside the powershell script as it would require to restart +# # the parent CMD process). +# - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" +# # add databases +# - "SET PATH=%POSTGRES_PATH%\bin;%MYSQL_PATH%\bin;%PATH%" +# +# # Check that we have the expected version and architecture for Python +# - "python --version" +# - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" +# +# # Upgrade to the latest version of pip to avoid it displaying warnings +# # about it being out of date. +# - "pip install --disable-pip-version-check --user --upgrade pip" +# +# # Install the build dependencies of the project. If some dependencies contain +# # compiled extensions and are not provided as pre-built wheel packages, +# # pip will build them from source using the MSVC compiler matching the +# # target Python version and architecture +# - "%CMD_IN_ENV% pip install -r dev-requirements.txt" +# +#build_script: +# # Build the compiled extension +# - "%CMD_IN_ENV% python setup.py build" +#build_script: +# # Build the compiled extension +# - "%CMD_IN_ENV% python setup.py build" +# build_script: +# # postgres +# - createdb odm2 +# - psql -d odm2 -a -f spec/databases/postgresql/schema/schema.sql +# # mysql +# - mysql -e "drop database test; create database odm2;" --user=root +# - mysql sqlectron < spec/databases/mysql/schema/schema.sql --user=root +# # sqlserver +# - ps: ./appveyor-sqlserver.ps1 SQL2008R2SP2 +# - sqlcmd -S localhost,1433 -U sa -P Password12! -Q "CREATE DATABASE odm2" -d "master" +# - sqlcmd -S localhost,1433 -U sa -P Password12! -i spec/databases/sqlserver/schema/schema.sql -d "odm2" +# - sqlcmd -S localhost,1433 -U sa -P Password12! -Q "select table_name from information_schema.tables" -d "odm2" +# +#test_script: +# # Run the project tests +# - "%CMD_IN_ENV% python setup.py nosetests" +# +#language: python +#python: +## - "2.6" +# - "2.7" +## - "3.2" +## - "3.3" +## - "3.4" +## - "3.5" +## - "3.5-dev" # 3.5 development branch +## - "nightly" # currently points to 3.6-dev +## command to install dependencies +# +#before_install: +##https://github.com/sqlectron/sqlectron-core/blob/master/appveyor.yml +# - mysql -e "CREATE USER 'ODM'@'localhost' IDENTIFIED BY 'odm';GRANT ALL PRIVILEGES ON *.* TO 'ODM'@'localhost';" -uroot +# - mysql -e "create database IF NOT EXISTS odm2;" -uroot +# - mysql -e "create database IF NOT EXISTS odm2test;" -uroot +# - psql -U postgres -c "create extension postgis" +# - psql -c 'DROP DATABASE IF EXISTS odm2test;' -U postgres; +# - psql -c 'create database odm2test;' -U postgres; +## - psql -U postgres -d odm2test -a -f ./tests/schemas/postgresql/ODM2_for_PostgreSQL.sql +# - psql -c 'DROP DATABASE IF EXISTS odm2;' -U postgres; +# - psql -c 'create database odm2;' -U postgres; +# # patterned after: https://github.com/ptrv/gpx2spatialite/blob/master/.travis.yml +## - sudo apt-get install -y python-software-properties +## - sudo apt-add-repository -y ppa:git-core/ppa +## - sudo apt-add-repository -y ppa:ubuntugis/ppa +## - sudo apt-get update -qq +## - sudo apt-get install unixodbc unixodbc-dev tdsodbc +## - sudo apt-get install freetds-dev freetds-bin +## - sudo apt-get install libc6 e2fsprogs # mssql driver +# # Spatialiate +## - sudo apt-get install -y libproj-dev libgeos-dev libspatialite-dev +## - sudo ln -s /usr/lib/x86_64-linux-gnu/libspatialite.so /usr/lib/libspatialite.so +## - sudo apt-get install python-scipy python-matplotlib python-pandas python-sympy python-nose +## - sudo apt-get install python-matplotlib python-pandas python-nose +# - pip install pandas +#install: # now just our code +# - pip install git+https://github.com/ODM2/geoalchemy.git@odm2#egg=geoalchemy-0.7.3 +# - pip install . +# - pip install -r requirements_tests.txt --allow-external pyodbc --allow-unverified pyodbc +# # pysqlite +# - pip install pysqlite +# - dir .\tests\usecasesql\littlebearriver\sampledatabases\odm2_mysql\LBR_MySQL_SmallExample.sql .\tests\usecasesql\marchantariats\marchantariats.sql +# - mysql --user root --verbose odm2 < .\tests\usecasesql\littlebearriver\sampledatabases\odm2_mysql\LBR_MySQL_SmallExample.sql +## add -a to psql to see full log +# - psql -U postgres -f ./tests/usecasesql/marchantariats/marchantariats.sql +# +## don't forget to open up the azure mssql server to these addreses +## https://docs.travis-ci.com/user/ip-addresses/ +# +## command to run tests +#script: +## just the connection part +# - py.test tests/test_connection.py +# - py.test +# diff --git a/ci-helpers/appveyor/install-miniconda.ps1 b/ci-helpers/appveyor/install-miniconda.ps1 new file mode 100644 index 0000000..87f1d04 --- /dev/null +++ b/ci-helpers/appveyor/install-miniconda.ps1 @@ -0,0 +1,196 @@ +# Sample script to install anaconda under windows +# Authors: Stuart Mumford +# Borrwed from: Olivier Grisel and Kyle Kastner +# License: BSD 3 clause + +$MINICONDA_URL = "https://repo.continuum.io/miniconda/" + +if (! $env:ASTROPY_LTS_VERSION) { + $env:ASTROPY_LTS_VERSION = "1.0" +} + +function DownloadMiniconda ($version, $platform_suffix) { + $webclient = New-Object System.Net.WebClient + $filename = "Miniconda2-" + $version + "-Windows-" + $platform_suffix + ".exe" + + $url = $MINICONDA_URL + $filename + + $basedir = $pwd.Path + "\" + $filepath = $basedir + $filename + if (Test-Path $filename) { + Write-Host "Reusing" $filepath + return $filepath + } + + # Download and retry up to 3 times in case of network transient errors. + Write-Host "Downloading" $filename "from" $url + $retry_attempts = 2 + for($i=0; $i -lt $retry_attempts; $i++){ + try { + $webclient.DownloadFile($url, $filepath) + break + } + Catch [Exception]{ + Start-Sleep 1 + } + } + if (Test-Path $filepath) { + Write-Host "File saved at" $filepath + } else { + # Retry once to get the error message if any at the last try + $webclient.DownloadFile($url, $filepath) + } + return $filepath +} + +function InstallMiniconda ($miniconda_version, $architecture, $python_home) { + Write-Host "Installing miniconda" $miniconda_version "for" $architecture "bit architecture to" $python_home + if (Test-Path $python_home) { + Write-Host $python_home "already exists, skipping." + return $false + } + if ($architecture -eq "x86") { + $platform_suffix = "x86" + } else { + $platform_suffix = "x86_64" + } + $filepath = DownloadMiniconda $miniconda_version $platform_suffix + Write-Host "Installing" $filepath "to" $python_home + $args = "/InstallationType=AllUsers /S /AddToPath=1 /RegisterPython=1 /D=" + $python_home + Write-Host $filepath $args + Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru + #Start-Sleep -s 15 + if (Test-Path $python_home) { + Write-Host "Miniconda $miniconda_version ($architecture) installation complete" + } else { + Write-Host "Failed to install Python in $python_home" + Exit 1 + } +} + +# Install miniconda, if no version is given use the latest +if (! $env:MINICONDA_VERSION) { + $env:MINICONDA_VERSION="latest" +} + +InstallMiniconda $env:MINICONDA_VERSION $env:PLATFORM $env:PYTHON + +# Set environment variables +$env:PATH = "${env:PYTHON};${env:PYTHON}\Scripts;" + $env:PATH + +# Conda config +conda config --set always_yes true + +if (! $env:CONDA_CHANNELS) { + $CONDA_CHANNELS=@("astropy", "astropy-ci-extras", "openastronomy") +} else { + $CONDA_CHANNELS=$env:CONDA_CHANNELS.split(" ") +} +foreach ($CONDA_CHANNEL in $CONDA_CHANNELS) { + conda config --add channels $CONDA_CHANNEL +} + +# Install the build and runtime dependencies of the project. +conda update -q conda + +# Create a conda environment using the astropy bonus packages +conda create -q -n test python=$env:PYTHON_VERSION +activate test + +# Set environment variables for environment (activate test doesn't seem to do the trick) +$env:PATH = "${env:PYTHON}\envs\test;${env:PYTHON}\envs\test\Scripts;${env:PYTHON}\envs\test\Library\bin;" + $env:PATH + +# Check that we have the expected version of Python +python --version + +# Check whether a specific version of Numpy is required +if ($env:NUMPY_VERSION) { + if($env:NUMPY_VERSION -match "stable") { + $NUMPY_OPTION = "numpy" + } elseif($env:NUMPY_VERSION -match "dev") { + $NUMPY_OPTION = "Cython pip".Split(" ") + } else { + $NUMPY_OPTION = "numpy=" + $env:NUMPY_VERSION + } +} else { + $NUMPY_OPTION = "" +} + +# Check whether a specific version of Astropy is required +if ($env:ASTROPY_VERSION) { + if($env:ASTROPY_VERSION -match "stable") { + $ASTROPY_OPTION = "astropy" + } elseif($env:ASTROPY_VERSION -match "dev") { + $ASTROPY_OPTION = "Cython pip jinja2".Split(" ") + } elseif($env:ASTROPY_VERSION -match "lts") { + $ASTROPY_OPTION = "astropy=" + $env:ASTROPY_LTS_VERSION + } else { + $ASTROPY_OPTION = "astropy=" + $env:ASTROPY_VERSION + } +} else { + $ASTROPY_OPTION = "" +} + +# Install the specified versions of numpy and other dependencies +if ($env:CONDA_DEPENDENCIES) { + $CONDA_DEPENDENCIES = $env:CONDA_DEPENDENCIES.split(" ") +} else { + $CONDA_DEPENDENCIES = "" +} + +# Due to scipy DLL issues with mkl 11.3.3, and as there is no nomkl option +# for windows, we should use mkl 11.3.1 for now as a workaround see discussion +# in https://github.com/astropy/astropy/pull/4907#issuecomment-219200964 + +if ($NUMPY_OPTION -ne "") { + $NUMPY_OPTION_mkl = "mkl=11.3.1 " + $NUMPY_OPTION + echo $NUMPY_OPTION_mkl + $NUMPY_OPTION = $NUMPY_OPTION_mkl.Split(" ") +} + +# We have to fix the version of the vs2015_runtime on Python 3.5 to avoid +# issues. See https://github.com/astropy/ci-helpers/issues/92 for more details. + +if ($env:PYTHON_VERSION -match "3.5") { + conda install -n test -q vs2015_runtime=14.00.23026.0=0 +} + +conda install -n test -q pytest $NUMPY_OPTION $ASTROPY_OPTION $CONDA_DEPENDENCIES + +# Check whether the developer version of Numpy is required and if yes install it +if ($env:NUMPY_VERSION -match "dev") { + Invoke-Expression "${env:CMD_IN_ENV} pip install git+https://github.com/numpy/numpy.git#egg=numpy --upgrade --no-deps" +} + +# Check whether the developer version of Astropy is required and if yes install +# it. We need to include --no-deps to make sure that Numpy doesn't get upgraded. +if ($env:ASTROPY_VERSION -match "dev") { + Invoke-Expression "${env:CMD_IN_ENV} pip install git+https://github.com/astropy/astropy.git#egg=astropy --upgrade --no-deps" +} + +#Invoke-Expression "${env:CMD_IN_ENV} pip install -e git+https://github.com/ODM2/geoalchemy.git@v0.7.4#egg=geoalchemy-0.7.4" + + + +# We finally install the dependencies listed in PIP_DEPENDENCIES. We do this +# after installing the Numpy versions of Numpy or Astropy. If we didn't do this, +# then calling pip earlier could result in the stable version of astropy getting +# installed, and then overritten later by the dev version (which would waste +# build time) + +if ($env:PIP_FLAGS) { + $PIP_FLAGS = $env:PIP_FLAGS +} else { + $PIP_FLAGS = "" +} + +if ($env:PIP_DEPENDENCIES) { + $PIP_DEPENDENCIES = $env:PIP_DEPENDENCIES.split(",") +} else { + $PIP_DEPENDENCIES = "" +} + +if ($env:PIP_DEPENDENCIES) { + pip install $PIP_DEPENDENCIES $PIP_FLAGS +} + diff --git a/ci-helpers/appveyor/sqlserver.ps1 b/ci-helpers/appveyor/sqlserver.ps1 new file mode 100644 index 0000000..f7a6b0a --- /dev/null +++ b/ci-helpers/appveyor/sqlserver.ps1 @@ -0,0 +1,21 @@ +[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null +[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | Out-Null + +$instancename = $args[0]; +$computerName = $env:COMPUTERNAME +$smo = 'Microsoft.SqlServer.Management.Smo.' +$wmi = New-Object ($smo + 'Wmi.ManagedComputer') + +$uri = "ManagedComputer[@Name='$computerName']/ ServerInstance[@Name='$instancename']/ServerProtocol[@Name='Tcp']" +$Tcp = $wmi.GetSmoObject($uri) +foreach ($ipAddress in $Tcp.IPAddresses) +{ + $ipAddress.IPAddressProperties["TcpDynamicPorts"].Value = "" + $ipAddress.IPAddressProperties["TcpPort"].Value = "1433" +} +$Tcp.Alter() + +Stop-Service SQLBrowser +Stop-Service "MSSQL`$$instancename" +Start-Service SQLBrowser +Start-Service "MSSQL`$$instancename" \ No newline at end of file diff --git a/ci-helpers/appveyor/windows_sdk.cmd b/ci-helpers/appveyor/windows_sdk.cmd new file mode 100644 index 0000000..951b0c7 --- /dev/null +++ b/ci-helpers/appveyor/windows_sdk.cmd @@ -0,0 +1,66 @@ +:: To build extensions for 64 bit Python 3.5 or later no special environment needs +:: to be configured. +:: +:: To build extensions for 64 bit Python 3.4 or earlier, we need to configure environment +:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) +:: +:: To build extensions for 64 bit Python 2, we need to configure environment +:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) +:: +:: 32 bit builds do not require specific environment configurations. +:: +:: Note: this script needs to be run with the /E:ON and /V:ON flags for the +:: cmd interpreter, at least for (SDK v7.0) +:: +:: More details at: +:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows +:: https://stackoverflow.com/a/13751649/163740 +:: +:: Original Author: Olivier Grisel +:: License: CC0 1.0 Universal: https://creativecommons.org/publicdomain/zero/1.0/ +:: This version based on updates for python 3.5 by Phil Elson at: +:: https://github.com/pelson/Obvious-CI/tree/master/scripts + +@ECHO OFF + +SET COMMAND_TO_RUN=%* +SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows + +SET MAJOR_PYTHON_VERSION="%PYTHON_VERSION:~0,1%" +SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% +IF %MAJOR_PYTHON_VERSION% == "2" ( + SET WINDOWS_SDK_VERSION="v7.0" + SET SET_SDK_64=Y +) ELSE IF %MAJOR_PYTHON_VERSION% == "3" ( + SET WINDOWS_SDK_VERSION="v7.1" + IF %MINOR_PYTHON_VERSION% LEQ 4 ( + SET SET_SDK_64=Y + ) ELSE ( + SET SET_SDK_64=N + ) +) ELSE ( + ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" + EXIT 1 +) + +IF "%PYTHON_ARCH%"=="64" ( + IF %SET_SDK_64% == Y ( + ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture + SET DISTUTILS_USE_SDK=1 + SET MSSdk=1 + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 + ) ELSE ( + ECHO Using default MSVC build environment for 64 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 + ) +) ELSE ( + ECHO Using default MSVC build environment for 32 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 +) \ No newline at end of file diff --git a/scripts/mysql_setup.sh b/ci-helpers/mysql_setup.sh similarity index 100% rename from scripts/mysql_setup.sh rename to ci-helpers/mysql_setup.sh diff --git a/scripts/postgres_setup.sh b/ci-helpers/postgres_setup.sh similarity index 100% rename from scripts/postgres_setup.sh rename to ci-helpers/postgres_setup.sh diff --git a/scripts/apt-get.sh b/ci-helpers/travis/apt-get.sh similarity index 100% rename from scripts/apt-get.sh rename to ci-helpers/travis/apt-get.sh diff --git a/scripts/freetds.sh b/ci-helpers/travis/freetds.sh similarity index 100% rename from scripts/freetds.sh rename to ci-helpers/travis/freetds.sh diff --git a/condaenvironment_1.yml b/condaenvironment_1.yml deleted file mode 100644 index 325b37e..0000000 --- a/condaenvironment_1.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: odm2api_env1 -channels: - - ioos -dependencies: - - python=2.7 - - pip - - ipython-notebook - - scipy - - pandas - - seaborn - - sqlalchemy - - psycopg2 - - pymysql - - pyodbc - - shapely diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..e421db0 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = python -msphinx +SPHINXPROJ = ODM2PythonAPI +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/doc/APIFunctionList.md b/docs/_NOTES/APIFunctionList.md similarity index 100% rename from doc/APIFunctionList.md rename to docs/_NOTES/APIFunctionList.md diff --git a/doc/DatabaseNotes.md b/docs/_NOTES/DatabaseNotes.md similarity index 100% rename from doc/DatabaseNotes.md rename to docs/_NOTES/DatabaseNotes.md diff --git a/doc/MySql.md b/docs/_NOTES/MySql.md similarity index 100% rename from doc/MySql.md rename to docs/_NOTES/MySql.md diff --git a/distribution_notes.txt b/docs/_NOTES/distribution_notes.txt similarity index 100% rename from distribution_notes.txt rename to docs/_NOTES/distribution_notes.txt diff --git a/notes_sqlacodegen.txt b/docs/_NOTES/notes_sqlacodegen.txt similarity index 100% rename from notes_sqlacodegen.txt rename to docs/_NOTES/notes_sqlacodegen.txt diff --git a/doc/wxFormBuilder/dbConfigurationPnl.fbp b/docs/_NOTES/wxFormBuilder/dbConfigurationPnl.fbp similarity index 100% rename from doc/wxFormBuilder/dbConfigurationPnl.fbp rename to docs/_NOTES/wxFormBuilder/dbConfigurationPnl.fbp diff --git a/docs/source/_static/logo.png b/docs/source/_static/logo.png new file mode 100644 index 0000000..ceccc7c Binary files /dev/null and b/docs/source/_static/logo.png differ diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..76865db --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +# +# ODM2PythonAPI documentation build configuration file, created by +# sphinx-quickstart on Thu Sep 28 11:03:57 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.viewcode', + 'sphinx.ext.napoleon', + 'sphinx.ext.autosummary' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'ODM2PythonAPI' +copyright = u'2017, Stephanie Reeder' +author = u'Stephanie Reeder' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. + +from odm2api._version import get_versions +version = release = get_versions()['version'] +del get_versions + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +html_theme_options = { + 'logo': 'logo.png', + 'logo_name': 'ODM2', + 'github_user': 'ODM2', + 'github_repo': 'ODM2PythonAPI', + 'github_banner': True, + 'travis_button': True, + 'fixed_sidebar': True, +} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# This is required for the alabaster theme +# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', # needs 'show_related': True theme option to display + 'searchbox.html', + 'donate.html', + ] +} + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'ODM2PythonAPIdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'ODM2PythonAPI.tex', u'ODM2PythonAPI Documentation', + u'Stephanie Reeder', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'odm2pythonapi', u'ODM2PythonAPI Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'ODM2PythonAPI', u'ODM2PythonAPI Documentation', + author, 'ODM2PythonAPI', 'One line description of project.', + 'Miscellaneous'), +] + + +autosummary_generate = True diff --git a/docs/source/contribute.rst b/docs/source/contribute.rst new file mode 100644 index 0000000..25103c0 --- /dev/null +++ b/docs/source/contribute.rst @@ -0,0 +1,37 @@ +Contribute to Documentation +============================ + +This guide is a reference on how to contribute to ODM2 Documentation effort +for the many `ODM2 Software Ecosystem `__. + +Conventions +----------- + +There are a few conventions that should be followed +when writing docstrings within the code: + +- Docstrings should follow + `Google Style Documentation + `__. + +- Do not say "**defaults to ____**" for any arguments, + unless the argument needs further explanation. + The default value is already available in the method/function definition. + +- If function needs to be instantiated, explicitly show in example. + See + `here `__ + for discussion of class vs instance methods. + +- Provide link to `Controlled Vocabulary `__ + if an argument needs a CV as value. + +Please add any additional conventions that you think should be in place +within `the github issue #106 `__. + +Pull requests +------------- + +Once changes has been in place within your forked copy of the repository +you are working on, please create a pull request to add your contribution +to the **master** branch of the repository. diff --git a/docs/source/credits.rst b/docs/source/credits.rst new file mode 100644 index 0000000..9ba5d88 --- /dev/null +++ b/docs/source/credits.rst @@ -0,0 +1,10 @@ +Credits +------- + +This work was supported by National Science Foundation Grants +`EAR-1224638 `__ +and +`ACI-1339834 `__. +Any opinions, findings, and conclusions or recommendations expressed in +this material are those of the author(s) and do not necessarily reflect +the views of the National Science Foundation. diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..c0fc138 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,26 @@ +ODM2 Python API +=============== + +A Python-based application programmer's interface for the `Observations Data Model 2 (ODM2) `__. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + installing + modules + odm2models + credits + contribute + +Indices and tables +================== + +.. toctree:: + :maxdepth: 2 + + models + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/installing.rst b/docs/source/installing.rst new file mode 100644 index 0000000..a135c24 --- /dev/null +++ b/docs/source/installing.rst @@ -0,0 +1,62 @@ +Installation +============ + +The easiest and most reliable way to install the ODM2 Python API +(``odm2api``) is using the `Conda package management +system `__ via either +`Anaconda `__ or +`Miniconda `__. To start using +conda (if it's not your system default), add conda to the PATH; on +OS X and Linux, it's something like +``export PATH=$HOME/miniconda3/bin:$PATH``, but the exact path may vary. + +To activate a conda environment, say, "myenv": + +.. code:: bash + + activate myenv # On Windows + source activate myenv # On MacOSX or Linux + +**Note:** ``odm2api`` currently is only tested on Python 2.7. Some +changes have been made to support Python 3.x, but they haven't been +tested thoroughly. + +Latest release, from ODM2 anaconda.org channel +---------------------------------------------- + +The `latest release `__ is available +on the `ODM2 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 + +All dependencies are installed, 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 + + +Installing the development version +---------------------------------- + +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 diff --git a/docs/source/models.rst b/docs/source/models.rst new file mode 100644 index 0000000..bd5bb0a --- /dev/null +++ b/docs/source/models.rst @@ -0,0 +1,27 @@ +ODM2 Models Index +================== + +ODM2 is organized with a "core" schema and multiple "extension" schemas that +extend the functionality of the core. The following sections cover some overarching concepts +for ODM2 and then focus on specific entities within the ODM2 Core schema and ODM2's extension schemas. + +ODM2Core Entities +------------------ + +The following are entities in the `ODM2 Core Schema `__: + +.. autosummary:: + + odm2api.ODM2.models.Actions + odm2api.ODM2.models.DataSets + odm2api.ODM2.models.FeatureActions + odm2api.ODM2.models.Methods + odm2api.ODM2.models.Organizations + odm2api.ODM2.models.People + odm2api.ODM2.models.ProcessingLevels + odm2api.ODM2.models.RelatedActions + odm2api.ODM2.models.Results + odm2api.ODM2.models.SamplingFeatures + odm2api.ODM2.models.TaxonomicClassifiers + odm2api.ODM2.models.Units + odm2api.ODM2.models.Variables \ No newline at end of file diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 0000000..c3aa99d --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,51 @@ +Developer Interface +=================== + +.. module:: odm2api + +This part of the documentation covers all the interfaces of ODM2PythonAPI. + +:mod:`Database Connection` +--------------------------- + +.. automodule:: odm2api.ODMconnection + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: odm2api.base + :members: + :undoc-members: + :show-inheritance: + +:mod:`Read Services` +--------------------- + +.. automodule:: odm2api.ODM2.services.readService + :members: + :undoc-members: + :show-inheritance: + +:mod:`Create Services` +----------------------- + +.. automodule:: odm2api.ODM2.services.createService + :members: + :undoc-members: + :show-inheritance: + +:mod:`Delete Services` +----------------------- + +.. automodule:: odm2api.ODM2.services.deleteService + :members: + :undoc-members: + :show-inheritance: + +:mod:`Update Services` +----------------------- + +.. automodule:: odm2api.ODM2.services.updateService + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/odm2models.rst b/docs/source/odm2models.rst new file mode 100644 index 0000000..2749f58 --- /dev/null +++ b/docs/source/odm2models.rst @@ -0,0 +1,7 @@ +ODM2 Models +=========== + +.. automodule:: odm2api.ODM2.models + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/github_deploy_key.enc b/github_deploy_key.enc new file mode 100644 index 0000000..8475f25 --- /dev/null +++ b/github_deploy_key.enc @@ -0,0 +1 @@ +gAAAAABZzlD-4Hs7URurlqa0t6qKw6oA3xSDt_p7Ep7m2nz7IDeiqJU2AtF8Z_a-W6ZNTFFLfXRdHmVZKl34cn3n-YJ49kqJOIA3-jwYs4sQAcIX_6AXDjOcWfrTf0GMmBlgSidEB8FBuLSHaylSr2iB3jhB5gyXfjUNepfW47TfNcHaaeweO-KAMZ6Y4qQPzv1Z6SN3Gs9K4zAzU8UuPD4kUwQnVYl1hy1sKKkCU_saGoyC0xd_LQDkp1KvwIkwtlsluCopoGPC1laFyMq4Xuuu7szvf6vDfKuwypsXkfBmlKxVwQRMLthVG4E8qnTBv_gCrBtOx9tvClJo5xtZwcm52fcNcWRbLZaLX3EYZY_GLTIK4aNl1xxzJMyzQLv-ITQQA76gt23J6AT29nGPXLWaH_hUN40G2p-ObwasKYMqiOwpNA8Yts6VcjusZTFFXAl05TDpqyLfF7qsUMafP95s9iuJ5vSzu1Q1Y0nRD-PDQbX7M89wpsngA37XbciVcjUB-oRsJRGHzwlzJweVRz9OUOV-2NjJbh-I6yU3U3FlInYHN2g_LgMSGRMjQR66ZTCeaeX0FOPuzeFmkTt-xSeMQ9MopeSwXpvvODYN9lOFMc7H2WMriiAE5X0cccotpXjZa4MUgf1v-kkpVC-njrWJTzydW0V1DbSo1YyNwILX8DsDh9xMLZd5-qoGKXzmBfuz8jVsQ_6V5NJSYUAQE4uFA56ybODC6Rmy1f4_Me_uCZwev_LPYqciZi1ZlP2iyRU2iCb-ydIOIPBYrwk-6hIyQILfNeB2l63z3zU6uUcAySdOLp79vKlylPvDU8am-09xvsK2UFM0Ok6722VAY_nxzp4gfUOWPQAr93ztnX-o8VG-5xGaynt4fyZiA0LcicCwpyi6BtLao23WZlShNHdEwtPm8_9p0pKnAgA8ZiQXJHkaIjOtOpmoZb73XmQHGVgy4MoHuoA0JBpYzuFFvDQhcHKOGQie6nxRH8Z8jlzdgcS3Tnxz2SDDrQ7jzkhFKgWRjnEuNTxbe-SBBtdVLfoqU50MXHNOKUcQ0gEQ97sX6WWjofLRSNfgrPMz7WM8HQL7lNsdcz6bodciL_z-0SgZg8-fD4Yy4XvNR6OUigG2F33yILr3rJl_s1NYERFB_0z3CNMbSBUFlPREzdrSwYDJ1rSNILhlJqt0AgLZA6yH-5a25A7Be-XX2ArMe2nt4tElumhd9MP7OhFV89O68zTPGwsq46A_C4sHAAUeXjOqPj_jfQc6u0B0Yxrtwh-fspk9e_O40UrQJfnxWIvQsv05ph1w0edk4n7DVx1Ie_jHI4wQSQgWU34OPxkt-ef9UvCTcyJjXrGp9Mc1y6fLnrqnQdjHFeVh9tN2JdB3ycdl_ooRN8MrrWugnRtUE2SRzDOZ5L3fVgvpq-1yweK6mBxu2NTwdgeIzuG-gH_DoDcf1H3YWkda9xMJYmAJN2HZQ4M7RlzGtKKlwRXNVeZJqySWzc2QI3Kt3ojQJfvWYcIOz1fBSHVPaxVze4Df6d2KLd1irMQarsSTEX43n-kzPmHe6D-K49qXKICyo3GkN_2aeTZPHyVkzT-DmXY6NykK9tFIMVa4V7PvUqRShceltuDs6IaFWsiuauV3I88zJmEWLde6UFxM8XqJ6H7UslgUub2e5hlTm8IL_VDDJV-jKEbJBY8NbWGtCe2n7oC01wzgBap3M1QxS9-IbpOmJdc31ZLh_r4XxL--tzrgmGcgWeyumfPcex8RwAWVNkOOKWqmw-atW6l-y0MnjCnlgCTZc-5PRw_rXa_7wOJT--LFF5Juu_TWj21dj1fcQX-Y8FvQcEwPuWMZC2vh87oxeFgK4PFsPlBaR0WwkdFD8xkGfuos5lnWdhE6wjR48g9ViRcXlwvFDlGt9uGrQYBMRadx5k08TAdZXhCZZj1002iZRtLjz8FiOrL524-iNdXOPQ9w86QgewmXdCGf-7V8o2PmedbVCLL5_dLvIw8hK3FQB0FT2BRnZZQXyvZ3RE9jOyMi2vDSCNLHzoy7dJ55yRI2Ut6jiAxrkkY6qM-e5OR9iHso9XCqUaQ1489l_owo3ZmNniTTFwnAxYzprjkDB3T_LQ3CwzcRvd2dWkcp6OxLIqnBo0q3YD35yx8JLzfXAYb2qZHbWPyH1QUZzv_9SZY6gRj1zhpewJ5EOhHn4xx1O13TULzMsx3llWvLWHatBy5WW-CBfhPWMtbrb5RgQ6N3p61A2yjB_UjvWpw348-xaFRHkx9dFZrp_03Ci7OrAzka4uXdB9R8Skudw3e8Or7PU2VJli1uHG_jXy131Kutb0pz5Y_VHuzwPGA39_Zusy34R_WSTnAkr7a84poagEVEJYrL3HpFlm7jsS6hPTbqVDB8K38462mdoeHF8b6axPVN_GzLxqqpumeIeoR_IDINeAaKtYypdRwj1Wpf7fKw2OQvT4sfBW2PKy0S5_bu_xL3jDxInxMhLsvYSSnJ9HTpUM7vo5cYHShfM7oK5UYCguTxCYkyuR8593tk8qCjJgUWhWvcVSXZnbZDs5yCfi7jgw8e0RFES1efxSp1J5wfzyiDdHGLHhGrLqcl9MXGBMGKdktw4_FstjcWIBlyb7mycVX9PgBhwui_We74YjALw9GgYJ1sD4qHx68JkYTfwrnAOd3SCLp7WP0yeAUAp1cuxHh8eyZreiujPXpjr_B9gZyRoaBt0rPfmjYNXXEXMEu4HYJGG767UZLJayx7ZA7lS75c975bnDxg0KkWCRerDiWogd8uWKMcUKxAOHDfMkeOT3HLUQxzpoc77b1oEOdttDsCRvNXA2anwQQvBMIHgdbUdPPYtf252_d8aUQPhwwyfJAxrK-p1TEixw4WbXGI_qnPpItIuDlCvbHoq7adnMed5kLw5okL6o-9Mg37eGqi2omwkSeN6Aq3I-ItCdR0J1nbmpyXOx_Kyz4H7MC_5NqDBdfn5uGPrt055UI711waD7ZvOaeuPSJ_-N4rfq3o2rD8OiA3sHlGZFlEknSdPswYi4CcX-N8kzJ1tZUIWVZwBOtTHfettmga__r6UeN9NgI0pCUZOlvI3OPKcZ2UkwTLox7yZP6xfcrKju0S7N4tdr79BptIlu39XLSBv3pJRgH--OsnsHbV7BrElQbDZJWZzdRcnF7w4qRNQ5t-nBnbmCjWTYfhOefNGbV1s9Nb44X0H2jXI-BYFrtRtZkK8bIkt0qBbw1mc_i95V8UEjY5-5G0kdd0E-MVMDI_rudrj6bTQA4TZaU7qo8c7jEIYgCjDjT-S-ng5hyEEP9e4T76WDACoCmILt54X95jmUP2DFKFhWY0dlzcAL1Ue4Dsws6wCuZ2imeKH-v8trJutC_VDqRQM43ku-1n1Lg2WQCl4Yb4uRkp_kBsJiGgNjVXNx5m7GKPSmgH4uwq7wtEnwVNpqzaproDWbQDXoxt4_vCrWj245hhQDZbP3O2lffm3_BW3G4lko-LyWatXcRE-AubbaxmO3vBfhF2A_kvKC9z7Q82lAS4B7LM5qFKbM11nVzfjiKyM3T2FNfMfC6FL1vC7Rqt4jeGm9OS2Cv_lDQFDi7l5oJrbmAx7q8INpBp915ok2EsKen9ow3WHq534ldNconjY7hLS8UzWa2diI48tfPWHPap3h7g4WY2lpHTQWTHoM8MBHPNahY1C65HVITzpjkroPqzoNUjbHjbvJmSJJpvvJTL2EdlBz4cGTEvjqlGUditpi4WWAMmf-D5jZIJbGlLtNlMGya9KDkIRq6c9lB5a5ewmznh8YcxGsimYtUgKrCMKIPh8IhDyA7LrMAZ9CyBn3frX-C5uQcTm-tAAfjufOuL8IVOdRAjnhLJMZNSgxyDlB2v7tvZ6rIHEuNvr_kfmamZpIqommPbYGSUMDHzSs1Ti1cUArUniAME2azz-noarMxpDwqvYwCWPea290HGkUDgr2eIZ9Se2ZsVMu1gcHAfmmL_aPfxt5HZNuVDZ3oTMXzYYDaHJPPySOJ9l-EPCnewHdRq0TPCGL0tf6ECWt1x7W9eFnaqL_KRSjAn5NlmZarpf1kiL6-Li49A3kE6EWbLodh9zU5vV4W3b75ZyrZn0whrSuA1c2_w1-XswmlBLpqqZuvQ80tx-Y_bKYpqoItyvKlbe4NYUByqPkdM0VQbMWALPBqKGPChWqXXMj5zeAUzh90_gUtYN984lKO-P2ZxknmtypBvSKHalFee1O0uPBgaEa0w7uKhcTGqaZTSGvDj7fm33ENPQdLYdZr7xJvdsLosxzELn7yxFm2q16PAog8ivl5gAYDXgEqSoElkdp3s0PQDcGpZGHvyYB-swg3P7k23VgRfBdXo7-6CRQVck4OFVWDELY2yGTpIGb0K1V54sO2JhLe-6B7LwpWY-Hv2mj0= \ No newline at end of file diff --git a/odm2api/ODM1_1_1/__init__.py b/odm2api/ODM1_1_1/__init__.py deleted file mode 100644 index a24dbc6..0000000 --- a/odm2api/ODM1_1_1/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__author__ = 'stephanie' diff --git a/odm2api/ODM1_1_1/memory_database.py b/odm2api/ODM1_1_1/memory_database.py deleted file mode 100644 index ca487a9..0000000 --- a/odm2api/ODM1_1_1/memory_database.py +++ /dev/null @@ -1,233 +0,0 @@ -import timeit -import logging -from odmtools.common.logger import LoggerTool -from odmtools.odmservices import SeriesService -from odmtools.odmdata import DataValue -from sqlalchemy import update, bindparam -from odmtools.common.taskServer import TaskServerMP -from multiprocessing import cpu_count, freeze_support - -tool = LoggerTool() -logger = tool.setupLogger(__name__, __name__ + '.log', 'w', logging.DEBUG) - - -class MemoryDatabase(object): - ### this code should be changed to work with the database abstract layer so that sql queries are not in the code - - # series_service is a SeriesService - def __init__(self, taskserver=None): - - self.editLoaded = False - self.df = None - # Series_Service handles remote database - self.series_service = None - # Memory_service handles in memory database - self.mem_service = SeriesService("sqlite:///:memory:") - # TODO clean up closing of program - # if taskserver is None: - #numproc = cpu_count() - #self.taskserver = TaskServerMP(numproc=numproc) - #else: - - self.taskserver = taskserver - - def reset_edit(self): - self.mem_service = SeriesService("sqlite:///:memory:") - - def set_series_service(self, service): - self.series_service = service - - - ############## - # DB Queries - ############## - - def getDataValuesDF(self): - logging.debug("update in memory dataframe") - - ''' - if self.taskserver: - results = self.taskserver.getCompletedTasks() - df=results['UpdateEditDF'] - #else: - # self.updateDF() - ''' - self.updateDF() - # pick up thread here before it is needed - logging.debug("done updating memory dataframe") - return self.df - - def getDataValues(self): - return self.mem_service.get_all_values() - - def getEditRowCount(self): - return len(self.df) - - def getEditColumns(self): - columns = [] - tmp_columns = self.df.columns.tolist() - tmp_columns.remove('DataValue') - tmp_columns.remove('LocalDateTime') - tmp_columns.remove('QualifierID') - columns.append('DataValue') - columns.append('LocalDateTime') - columns.append('QualifierID') - columns.extend(tmp_columns) - return [(x, i) for (i, x) in enumerate(columns)] - # return [(x, i) for (i, x) in enumerate(self.df.columns)] - - def getDataValuesforGraph(self, seriesID, noDataValue, startDate=None, endDate=None): - return self.series_service.get_plot_values(seriesID, noDataValue, startDate, endDate) - - def getEditDataValuesforGraph(self): - return self.mem_service.get_all_plot_values() - - def commit(self): - self.mem_service._edit_session.commit() - - def rollback(self): - self.mem_service._edit_session.rollback() - # self.mem_service._session_factory.engine.connect().connection.rollback() - #self.updateDF() - - def update(self, updates): - - stmt = (DataValue.__table__.update(). - where(DataValue.id == bindparam('id')). - values(DataValue=bindparam('value')) - ) - - self.mem_service._edit_session.execute(stmt, updates) - - # self.updateDF() - - - def updateValue(self, ids, operator, value): - # query = DataValue.data_value+value - if operator == '+': - query = DataValue.data_value + value - elif operator == '-': - query = DataValue.data_value - value - elif operator == '*': - query = DataValue.data_value * value - elif operator == '=': - query = value - - - #break into chunks to get around sqlites restriction. allowing user to send in only 999 arguments at once - chunks=self.chunking(ids) - for c in chunks: - q=self.mem_service._edit_session.query(DataValue).filter(DataValue.id.in_(c)) - q.update({DataValue.data_value: query}, False) - - #self.updateDF() - - def chunking(self, data): - return [data[x:x+998] for x in xrange(0, len(data), 998)] - - #break into chunks to get around sqlites restriction. allowing user to send in only 999 arguments at once - def updateFlag(self, ids, value): - chunks=self.chunking(ids) - for c in chunks: - self.mem_service._edit_session.query(DataValue).filter(DataValue.id.in_(c))\ - .update({DataValue.qualifier_id: value}, False) - - - def delete(self, ids): - chunks=self.chunking(ids) - for c in chunks: - self.mem_service.delete_dvs(c) - #self.updateDF() - - - def addPoints(self, points): - """ - Takes in a list of points and loads each point into the database - """ - stmt = DataValue.__table__.insert() - - if not isinstance(points, list): - points = [points] - - for point in points: - vals = {"DataValue": point[0], "ValueAccuracy": point[1], - "LocalDateTime": point[2], "UTCOffset": point[3], - "DateTimeUTC": point[4], "OffsetValue": point[5], - "OffsetTypeID": point[6], "CensorCode": point[7], - "QualifierID": point[8], "SampleID": point[9], - "SiteID": point[10], "VariableID": point[11], - "MethodID": point[12], "SourceID": point[13], - "QualityControlLevelID": point[14]} - self.mem_service._edit_session.execute(stmt, vals) - - - def stopEdit(self): - self.editLoaded = False - self.df = None - - - def setConnection(self, service): - self.mem_service = service - - - # TODO multiprocess this function - def updateDF(self): - ''' - if self.taskserver: - # Give tasks to the taskserver to run parallelly - logger.debug("Sending tasks to taskserver") - self.taskserver.setTasks(("UpdateEditDF", self.mem_service)) - self.taskserver.processTasks() - else: - ''' - self.df = self.mem_service.get_all_values_df() - - def initEditValues(self, seriesID): - """ - :param df: dataframe - :return: nothing - """ - if not self.editLoaded: - logger.debug("Load series from db") - - self.df = self.series_service.get_values_by_series(seriesID) - self.editLoaded = True - - ''' - if self.taskserver: - self.taskserver.setTasks([("InitEditValues", (self.mem_service._session_factory.engine, self.df))]) - self.taskserver.processTasks() - # results = self.taskserver.getCompletedTasks() - # self.conn = results["InitEditValues"] - else: - ''' #TODO: Thread this call - if len(self.df)>0: - self.df.to_sql(name="DataValues", if_exists='replace', con=self.mem_service._session_factory.engine, - index=False)#,flavor='sqlite', chunksize=10000) - logger.debug("done loading database") - else: - logger.debug("no data in series") - - def changeSeriesIDs(self, var=None, qcl=None, method=None): - """ - - :param var: - :param qcl: - :param method: - :return: - """ - - query = self.mem_service._edit_session.query(DataValue) - if var is not None: - logger.debug(var) - query.update({DataValue.variable_id: var}) - - if method is not None: - logger.debug(method) - query.update({DataValue.method_id: method}) - # check that the code is not zero - # if qcl is not None and qcl.code != 0: - if qcl is not None: - logger.debug(qcl) - query.update({DataValue.quality_control_level_id: qcl}) - diff --git a/odm2api/ODM1_1_1/models.py b/odm2api/ODM1_1_1/models.py deleted file mode 100644 index 0ea54de..0000000 --- a/odm2api/ODM1_1_1/models.py +++ /dev/null @@ -1,462 +0,0 @@ - -from sqlalchemy.ext.declarative import declarative_base - - -from collections import OrderedDict # Requires Python 2.7 >= -from sqlalchemy import Column, Integer, Float, DateTime, ForeignKey, String, Boolean -from sqlalchemy.orm import relationship - - -Base = declarative_base() -metadata = Base.metadata - - -class SpeciationCV(Base): - __tablename__ = 'SpeciationCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class TopicCategoryCV(Base): - __tablename__ = 'TopicCategoryCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class Unit(Base): - __tablename__ = 'Units' - - id = Column('UnitsID', Integer, primary_key=True) - name = Column('UnitsName', String) - type = Column('UnitsType', String) - abbreviation = Column('UnitsAbbreviation', String) # (convert_unicode=True)) - - def __repr__(self): - return "" % (self.id, self.name, self.type) - - -class ValueTypeCV(Base): - __tablename__ = 'ValueTypeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class CensorCodeCV(Base): - __tablename__ = 'CensorCodeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class DataTypeCV(Base): - __tablename__ = 'DataTypeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - - - - -class GeneralCategoryCV(Base): - __tablename__ = 'GeneralCategoryCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class ISOMetadata(Base): - __tablename__ = 'ISOMetadata' - - id = Column('MetadataID', Integer, primary_key=True) - topic_category = Column('TopicCategory', String, nullable=False) - title = Column('Title', String, nullable=False) - abstract = Column('Abstract', String, nullable=False) - profile_version = Column('ProfileVersion', String, nullable=False) - metadata_link = Column('MetadataLink', String) - - def __repr__(self): - return "" % (self.id, self.topic_category, self.title) - - -class LabMethod(Base): - __tablename__ = 'LabMethods' - - id = Column('LabMethodID', Integer, primary_key=True) - name = Column('LabName', String, nullable=False) - organization = Column('LabOrganization', String, nullable=False) - method_name = Column('LabMethodName', String, nullable=False) - method_description = Column('LabMethodDescription', String, nullable=False) - method_link = Column('LabMethodLink', String) - - def __repr__(self): - return "" % (self.id, self.name, self.organization, self.method_name) - - -class Method(Base): - __tablename__ = 'Methods' - - id = Column('MethodID', Integer, primary_key=True) - description = Column('MethodDescription', String, nullable=False) - link = Column('MethodLink', String) - - def __repr__(self): - return "" % (self.id, self.description, self.link) - - -class ODMVersion(Base): - __tablename__ = 'ODMVersion' - - version_number = Column('VersionNumber', String, primary_key=True) - - def __repr__(self): - return "" % (self.version_number) - - -class OffsetType(Base): - __tablename__ = 'OffsetTypes' - - id = Column('OffsetTypeID', Integer, primary_key=True) - unit_id = Column('OffsetUnitsID', Integer, ForeignKey('Units.UnitsID'), nullable=False) - description = Column('OffsetDescription', String) - - # relationships - unit = relationship(Unit) - - def __repr__(self): - return "" % (self.id, self.unit_id, self.description) - - -class Qualifier(Base): - __tablename__ = 'Qualifiers' - - id = Column('QualifierID', Integer, primary_key=True) - code = Column('QualifierCode', String, nullable=False) - description = Column('QualifierDescription', String, nullable=False) - - def __repr__(self): - return "" % (self.id, self.code, self.description) - - -class QualityControlLevel(Base): - __tablename__ = 'QualityControlLevels' - - id = Column('QualityControlLevelID', Integer, primary_key=True) - code = Column('QualityControlLevelCode', String, nullable=False) - definition = Column('Definition', String, nullable=False) - explanation = Column('Explanation', String, nullable=False) - - def __repr__(self): - return "" % (self.id, self.code, self.definition, self.explanation) - - -class Sample(Base): - __tablename__ = 'Samples' - - id = Column('SampleID', Integer, primary_key=True) - type = Column('SampleType', String, nullable=False) - lab_sample_code = Column('LabSampleCode', String, nullable=False) - lab_method_id = Column('LabMethodID', Integer, ForeignKey('LabMethods.LabMethodID'), nullable=False) - - # relationships - lab_method = relationship(LabMethod) - - def __repr__(self): - return "" % (self.id, self.type, self.lab_sample_code, self.lab_method_id) - - -class SampleMediumCV(Base): - __tablename__ = 'SampleMediumCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class SampleTypeCV(Base): - __tablename__ = 'SampleTypeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - -class SpatialReference(Base): - __tablename__ = 'SpatialReferences' - - id = Column('SpatialReferenceID', Integer, primary_key=True) - srs_id = Column('SRSID', Integer) - srs_name = Column('SRSName', String) - is_geographic = Column('IsGeographic', Boolean) - notes = Column('Notes', String) - - def __repr__(self): - return "" % (self.id, self.srs_name) - -class Site(Base): - __tablename__ = 'Sites' - - id = Column('SiteID', Integer, primary_key=True) - code = Column('SiteCode', String) - name = Column('SiteName', String) - latitude = Column('Latitude', Float) - longitude = Column('Longitude', Float) - lat_long_datum_id = Column('LatLongDatumID', Integer, ForeignKey('SpatialReferences.SpatialReferenceID')) - elevation_m = Column('Elevation_m', Float) - vertical_datum_id = Column('VerticalDatum', Integer) - local_x = Column('LocalX', Float) - local_y = Column('LocalY', Float) - local_projection_id = Column('LocalProjectionID', Integer, ForeignKey('SpatialReferences.SpatialReferenceID')) - pos_accuracy_m = Column('PosAccuracy_m', Float) - state = Column('State', String) - county = Column('County', String) - comments = Column('Comments', String) - - type = Column('SiteType', String) - - # relationships - spatial_ref = relationship(SpatialReference, primaryjoin=("SpatialReference.id==Site.lat_long_datum_id")) - local_spatial_ref = relationship(SpatialReference, primaryjoin=("SpatialReference.id==Site.local_projection_id")) - - def __init__(self, site_code, site_name): - self.code = site_code - self.name = site_name - - def __repr__(self): - return "" % (self.code, self.name) - - -class SiteTypeCV(Base): - __tablename__ = 'SiteTypeCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class Source(Base): - __tablename__ = 'Sources' - - id = Column('SourceID', Integer, primary_key=True) - organization = Column('Organization', String, nullable=False) - description = Column('SourceDescription', String, nullable=False) - link = Column('SourceLink', String) - contact_name = Column('ContactName', String, nullable=False) - phone = Column('Phone', String, nullable=False) - email = Column('Email', String, nullable=False) - address = Column('Address', String, nullable=False) - city = Column('City', String, nullable=False) - state = Column('State', String, nullable=False) - zip_code = Column('ZipCode', String, nullable=False) - citation = Column('Citation', String, nullable=False) - iso_metadata_id = Column('MetadataID', Integer, ForeignKey('ISOMetadata.MetadataID'), nullable=False) - - # relationships - iso_metadata = relationship(ISOMetadata) - - def __repr__(self): - return "" % (self.id, self.organization, self.description) - - - - - -class Variable(Base): - __tablename__ = 'Variables' - - id = Column('VariableID', Integer, primary_key=True) - code = Column('VariableCode', String, nullable=False) - name = Column('VariableName', String, nullable=False) - speciation = Column('Speciation', String, nullable=False) - variable_unit_id = Column('VariableUnitsID', Integer, ForeignKey('Units.UnitsID'), nullable=False) - sample_medium = Column('SampleMedium', String, nullable=False) - value_type = Column('ValueType', String, nullable=False) - is_regular = Column('IsRegular', Boolean, nullable=False) - time_support = Column('TimeSupport', Float, nullable=False) - time_unit_id = Column('TimeUnitsID', Integer, ForeignKey('Units.UnitsID'), nullable=False) - data_type = Column('DataType', String, nullable=False) - general_category = Column('GeneralCategory', String, nullable=False) - no_data_value = Column('NoDataValue', Float, nullable=False) - - # relationships - variable_unit = relationship(Unit, primaryjoin=( - "Unit.id==Variable.variable_unit_id")) # <-- Uses class attribute names, not table column names - time_unit = relationship(Unit, primaryjoin=("Unit.id==Variable.time_unit_id")) - - def __repr__(self): - return "" % (self.id, self.code, self.name) - - -class VariableNameCV(Base): - __tablename__ = 'VariableNameCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class VerticalDatumCV(Base): - __tablename__ = 'VerticalDatumCV' - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class DataValue(Base): - __tablename__ = 'DataValues' - - id = Column('ValueID', Integer, primary_key=True) - data_value = Column('DataValue', Float) - value_accuracy = Column('ValueAccuracy', Float) - local_date_time = Column('LocalDateTime', DateTime) - utc_offset = Column('UTCOffset', Float) - date_time_utc = Column('DateTimeUTC', DateTime) - site_id = Column('SiteID', Integer, ForeignKey('Sites.SiteID'), nullable=False) - variable_id = Column('VariableID', Integer, ForeignKey('Variables.VariableID'), nullable=False) - offset_value = Column('OffsetValue', Float) - offset_type_id = Column('OffsetTypeID', Integer, ForeignKey('OffsetTypes.OffsetTypeID')) - censor_code = Column('CensorCode', String) - qualifier_id = Column('QualifierID', Integer, ForeignKey('Qualifiers.QualifierID')) - method_id = Column('MethodID', Integer, ForeignKey('Methods.MethodID'), nullable=False) - source_id = Column('SourceID', Integer, ForeignKey('Sources.SourceID'), nullable=False) - sample_id = Column('SampleID', Integer, ForeignKey('Samples.SampleID')) - derived_from_id = Column('DerivedFromID', Integer) - quality_control_level_id = Column('QualityControlLevelID', Integer, - ForeignKey('QualityControlLevels.QualityControlLevelID'), nullable=False) - - # relationships - site = relationship(Site) - variable = relationship(Variable) - method = relationship(Method) - source = relationship(Source) - quality_control_level = relationship(QualityControlLevel) - - qualifier = relationship(Qualifier) - offset_type = relationship(OffsetType) - sample = relationship(Sample) - - def list_repr(self): - return [self.id, self.data_value, self.value_accuracy, self.local_date_time, - self.utc_offset, self.date_time_utc, self.site_id, self.variable_id, - self.offset_value, self.offset_type_id, self.censor_code, self.qualifier_id, - self.method_id, self.source_id, self.sample_id, self.derived_from_id, - self.quality_control_level_id] - - def __repr__(self): - return "" % (self.data_value, self.local_date_time, self.value_accuracy) - - -class Series(Base): - __tablename__ = 'SeriesCatalog' - - id = Column('SeriesID', Integer, primary_key=True) - site_id = Column('SiteID', Integer, ForeignKey('Sites.SiteID'), nullable=False) - site_code = Column('SiteCode', String) - site_name = Column('SiteName', String) - variable_id = Column('VariableID', Integer, ForeignKey('Variables.VariableID'), nullable=False) - variable_code = Column('VariableCode', String) - variable_name = Column('VariableName', String) - speciation = Column('Speciation', String) - variable_units_id = Column('VariableUnitsID', Integer) - variable_units_name = Column('VariableUnitsName', String) - sample_medium = Column('SampleMedium', String) - value_type = Column('ValueType', String) - time_support = Column('TimeSupport', Float) - time_units_id = Column('TimeUnitsID', Integer) - time_units_name = Column('TimeUnitsName', String) - data_type = Column('DataType', String) - general_category = Column('GeneralCategory', String) - method_id = Column('MethodID', Integer, ForeignKey('Methods.MethodID'), nullable=False) - method_description = Column('MethodDescription', String) - source_id = Column('SourceID', Integer, ForeignKey('Sources.SourceID'), nullable=False) - source_description = Column('SourceDescription', String) - organization = Column('Organization', String) - citation = Column('Citation', String) - quality_control_level_id = Column('QualityControlLevelID', Integer, - ForeignKey('QualityControlLevels.QualityControlLevelID'), nullable=False) - quality_control_level_code = Column('QualityControlLevelCode', String) - begin_date_time = Column('BeginDateTime', DateTime) - end_date_time = Column('EndDateTime', DateTime) - begin_date_time_utc = Column('BeginDateTimeUTC', DateTime) - end_date_time_utc = Column('EndDateTimeUTC', DateTime) - value_count = Column('ValueCount', Integer) - - data_values = relationship("DataValue", - primaryjoin="and_(DataValue.site_id == Series.site_id, " - "DataValue.variable_id == Series.variable_id, " - "DataValue.method_id == Series.method_id, " - "DataValue.source_id == Series.source_id, " - "DataValue.quality_control_level_id == Series.quality_control_level_id)", - foreign_keys="[DataValue.site_id, DataValue.variable_id, DataValue.method_id, DataValue.source_id, DataValue.quality_control_level_id]", - order_by="DataValue.local_date_time", - backref="series") - - site = relationship(Site) - variable = relationship(Variable) - method = relationship(Method) - source = relationship(Source) - quality_control_level = relationship(QualityControlLevel) - - # TODO add all to repr - def __repr__(self): - return "" % (self.id, self.site_name, self.variable_code, self.variable_name) - - def get_table_columns(self): - return self.__table__.columns.keys() - - def list_repr(self): - return [self.id, self.site_id, self.site_code, self.site_name, self.variable_id, self.variable_code, - self.variable_name, self.speciation, self.variable_units_id, self.variable_units_name, - self.sample_medium, self.value_type, self.time_support, self.time_units_id, self.time_units_name, - self.data_type, self.general_category, self.method_id, self.method_description, - self.source_id, self.source_description, self.organization, self.citation, - self.quality_control_level_id, self.quality_control_level_code, self.begin_date_time, - self.end_date_time, self.begin_date_time_utc, self.end_date_time_utc, self.value_count] - - -def returnDict(): - keys = ['SeriesID', 'SiteID', 'SiteCode', 'SiteName', 'VariableID', 'VariableCode', 'VariableName', 'Speciation', - 'VariableUnitsID', 'VariableUnitsName', 'SampleMedium', 'ValueType', 'TimeSupport', 'TimeUnitsID', - 'TimeUnitsName', 'DataType', 'GeneralCategory', 'MethodID', 'MethodDescription', 'SourceID', - 'SourceDescription', 'Organization', 'Citation', 'QualityControlLevelID', 'QualityControlLevelCode', - 'BeginDateTime', 'EndDateTime', 'BeginDateTimeUTC', 'EndDateTimeUTC', 'ValueCount' - ] - values = ['id', 'site_id', 'site_code', 'site_name', 'variable_id', 'variable_code', 'variable_name', 'speciation', - 'variable_units_id', 'variable_units_name', 'sample_medium', 'value_type', 'time_support', - 'time_units_id', 'time_units_name', 'data_type', 'general_category', 'method_id', 'method_description', - 'source_id', 'source_description', 'organization', 'citation', 'quality_control_level_id', - 'quality_control_level_code', 'begin_date_time', 'end_date_time', 'begin_date_time_utc', - 'end_date_time_utc', 'value_count' - ] - return OrderedDict(zip(keys, values)) diff --git a/odm2api/ODM1_1_1/services/__init__.py b/odm2api/ODM1_1_1/services/__init__.py deleted file mode 100644 index 3635c4a..0000000 --- a/odm2api/ODM1_1_1/services/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -__author__ = 'stephanie' -# from cv_service import CVService, refreshDB -from series_service import ODM, SeriesService -from edit_service import EditService -from export_service import ExportService - -__all__ = [ 'SeriesService', 'EditService', 'ExportService', 'ODM'] -# 'CVService', -# def switch_service(version ): -# cv_service.refreshDB(version) -# series_service.refreshDB(version) \ No newline at end of file diff --git a/odm2api/ODM1_1_1/services/edit_service.py b/odm2api/ODM1_1_1/services/edit_service.py deleted file mode 100644 index 352296e..0000000 --- a/odm2api/ODM1_1_1/services/edit_service.py +++ /dev/null @@ -1,585 +0,0 @@ -import sqlite3 - -#from ...versionSwitcher import ODM -from series_service import SeriesService - -#from odmtools.odmdata import series as series_module - -import pandas as pd -import datetime -import numpy as np - -#import logging -#from odmtools.common.logger import LoggerTool - -#tool = LoggerTool() -#logger = tool.setupLogger(__name__, __name__ + '.log', 'w', logging.DEBUG) - - - - -class EditService(): - # Mutual exclusion: cursor, or connection_string - def __init__(self, series_id, connection=None, connection_string="", debug=False): - ''' - - :param series_id: - :param connection: memory database, contains connection to remote database - :param connection_string: connection to remote database - :param debug: - :return: - ''' - - self._series_id = series_id - self._filter_from_selection = False - self._debug = debug - - if connection_string is "" and connection is not None: - self.memDB= connection - #self._series_service = self.memDB.series_service#SeriesService(connection_string, debug) - - elif connection_string is not "" and connection is None: - from ..memory_database import MemoryDatabase - self.memDB= MemoryDatabase()#(series_service) - self.memDB.set_series_service(SeriesService(connection_string, False)) - - - else: - print ("ERROR: must send in either a remote db connection string or a memory database object") - - #logger.debug("Initializing Memory Database") - self.memDB.initEditValues(series_id) - #logger.debug("Finished Initializing Memory Database") - self._populate_series() - self.reset_filter() - - def get_series_service(self): - return self.memDB.series_service - - def _populate_series(self): - # [(ID, value, datetime), ...] - #self._cursor.execute("SELECT ValueID, DataValue, LocalDateTime FROM DataValues ORDER BY LocalDateTime") - - self._series_points_df = self.memDB.getDataValuesDF() - - - def _test_filter_previous(self): - - ''' - if not self._filter_from_selection: - self.reset_filter() - ''' - - df = None - - if not self._filter_from_selection: - df = self._series_points_df - else: - df = self.filtered_dataframe - - # Ensure that we're not working with an empty dataframe - - if isinstance(df, pd.DataFrame): - if df.empty: - return self._series_points_df - else: - if not df: - return self._series_points_df - - return df - - def datetime2dataframe(self, datetime_list): - """ Converts datetime_list to a pandas Dataframe - - - :param datetime_list: - :return Pandas.DataFrame: - """ - - result = None - - if isinstance(datetime_list, list): - - result = pd.DataFrame(datetime_list, columns=["LocalDateTime"]) - - result.set_index("LocalDateTime", inplace=True) - - return result - - ################### - # Stubs - ################### - def selectPointsStub(self): - """ - :param filtered_dataframe: - :return: - """ - - ## Convert dataframe into list of datetimes - - filtered_dataframe = self.get_filtered_points() - if isinstance(filtered_dataframe, pd.DataFrame): - if not filtered_dataframe.empty: - datetime_list = filtered_dataframe.index.to_pydatetime() - return datetime_list.tolist() - return [] - - ################### - # Filters - ################### - # operator is a character, either '<' or '>' - def filter_value(self, value, ops): - df = self._test_filter_previous() - - if ops == '>': - self.filtered_dataframe = df[df['DataValue'] > value] - - if ops == '<': - self.filtered_dataframe = df[df['DataValue'] < value] - - - def filter_date(self, before, after): - df = self._test_filter_previous() - if before and after: - self.filtered_dataframe = df[(df.index < before) & (df.index > after)] - - # Data Gaps - def data_gaps(self, value, time_period): - df = self._test_filter_previous() - - time_units = { - 'second': 's', - 'minute': 'm', - 'hour': 'h', - 'day': 'D', - 'week': 'W', - 'month': 'M', - 'year': 'Y' - } - - # make a copy of the dataframe in order to modify it to be in the form we need to determine data gaps - copy_df = df - copy_df['datetime'] = df.index - copy_df['dateprev'] = copy_df['datetime'].shift() - - # ensure that 'value' is an integer - if not isinstance(value, int): - value = int(value) - - # create a bool column indicating which rows meet condition - filtered_results = copy_df['datetime'].diff() >= np.timedelta64(value, time_units[time_period]) - - # filter on rows that passed previous condition - copy_df = copy_df[filtered_results] - - # merge values and remove duplicates. this hack allows for both values to be marked when selecting data gaps - newdf = pd.concat([copy_df['datetime'], copy_df['dateprev']], join='inner') - self.filtered_dataframe = df[df.index.isin(newdf.drop_duplicates().dropna())] - - # clean up - del copy_df - del filtered_results - del newdf - - def change_value_threshold(self, value, operator): - - df = self._test_filter_previous() - - # make a copy of the dataframe in order to modify it to be in the form we need to determine data gaps - copy_df = df - copy_df['values'] = df['DataValue'] - copy_df['diff'] = copy_df['values'].shift() - copy_df["diff_date"] = copy_df['LocalDateTime'].shift() - copy_df['change_threshold'] = abs(df['values'] - df['diff']) - - if not isinstance(value, float): - print("Need to have a float") - return - - copy_df['threshold'] = value - - if operator == ">": - copy_df['matches'] = df['change_threshold'] >= copy_df['threshold'] - - if operator == "<": - copy_df['matches'] = df['change_threshold'] <= copy_df['threshold'] - - filtered_df = copy_df[copy_df['matches']] - tmplist = filtered_df['diff_date'].tolist() + filtered_df.index.tolist() - del copy_df - self.filtered_dataframe = df[df.index.isin(tmplist)] - - - def select_points_tf(self, tf_list): - self._filter_list = tf_list - - #def select_points(self, id_list=[], datetime_list=[]): - def select_points(self, id_list=[], dataframe=[]): - #self.reset_filter() - - # This should be either one or the other. If it's both, id is used first. - # If neither are set this function does nothing. - - if len(id_list) > 0: - for i in range(len(self._series_points)): - if self._series_points[i][0] in id_list: - self._filter_list[i] = True - - if isinstance(dataframe, pd.DataFrame): - result = dataframe.index.astype(datetime.datetime) - self.filtered_dataframe = self._series_points_df[self._series_points_df.index.isin(dataframe.index)] - - - def reset_filter(self): - self.filtered_dataframe = None - - def filter_from_previous(self, value): - self._filter_from_selection = value - - def get_toggle(self): - return self._filter_from_selection - - - ################### - # Gets - ################### - def get_series(self): - return self.memDB.series_service.get_series_by_id(self._series_id) - - def get_series_points(self): - # all point in the series - return self._series_points - - def get_series_points_df(self): - """ - :return Pandas DataFrame: - """ - return self._series_points_df - - def get_filtered_points(self): - """ - :return Pandas DataFrame: - """ - if isinstance(self.filtered_dataframe, pd.DataFrame): - if self.filtered_dataframe.empty: - return None - else: - if not self.filtered_dataframe: - return None - if len(self.filtered_dataframe) > 0: - return self.filtered_dataframe - return None - - def get_filtered_dates(self): - return self.filtered_dataframe - - def get_filter_list(self): - # true or false list the length of the entire series. true indicate the point is selected - return self._filter_list - - def get_qcl(self, qcl_id): - return self.memDB.series_service.get_qcl_by_id(qcl_id) - - def get_method(self, method_id): - return self.memDB.series_service.get_method_by_id(method_id) - - def get_variable(self, variable_id): - #logger.debug(variable_id) - return self.memDB.series_service.get_variable_by_id(variable_id) - - - ################# - # Edits - ################# - - def change_value(self, value, operator): - filtered_points = self.get_filtered_points() - - ids = filtered_points.index.tolist()#["ValueID"].astype(int).tolist() - self.memDB.updateValue(ids, operator, float(value)) - self._populate_series() - - ## update filtered_dataframe - self.filtered_dataframe = self._series_points_df[self._series_points_df.index.isin(ids)] - - def add_points(self, points): - # todo: add the ability to send in multiple datetimes to a single 'point' - - self.memDB.addPoints(points) - - self._populate_series() - self.reset_filter() - - def delete_points(self): - filtered_points = self.get_filtered_points() - if not filtered_points.empty: - values = filtered_points.index.tolist()#['ValueID'].astype(float).tolist() - - self.memDB.delete(values) - self._populate_series() - self.filtered_dataframe = None - - def interpolate(self): - ''' - In [75]: ser = Series(np.sort(np.random.uniform(size=100))) - # interpolate at new_index - In [76]: new_index = ser.index | Index([49.25, 49.5, 49.75, 50.25, 50.5, 50.75]) - In [77]: interp_s = ser.reindex(new_index).interpolate(method='pchip') - ''' - - tmp_filter_list =self.get_filtered_points() - df = self._series_points_df - issel = df.index.isin(tmp_filter_list.index) - - mdf = df["DataValue"].mask(issel) - mdf.interpolate(method = "time", inplace=True) - tmp_filter_list["DataValue"]=mdf[issel] - ids = tmp_filter_list.index.tolist() - - #update_list = [(row["DataValue"], row["ValueID"]) for index, row in tmp_filter_list.iterrows()] - update_list = [{"value": row["DataValue"], "id": index} for index, row in tmp_filter_list.iterrows()] - - self.memDB.update(update_list) - - - self._populate_series() - - self.filtered_dataframe = self._series_points_df[self._series_points_df.index.isin(ids)] - - def drift_correction(self, gap_width): - if self.isOneGroup(): - tmp_filter_list =self.get_filtered_points() - startdate =tmp_filter_list.index[0] - x_l = (tmp_filter_list.index[-1]-startdate).total_seconds() - - # y_n = y_0 + G(x_i / x_l) - f = lambda row : row["DataValue"]+(gap_width * ((row.name-startdate).total_seconds() / x_l)) - tmp_filter_list["DataValue"]=tmp_filter_list.apply(f, axis = 1) - - update_list = [{"value": row["DataValue"], "id": index} for index, row in tmp_filter_list.iterrows()] - - ids = tmp_filter_list.index.tolist()#['ValueID'].tolist() - self.memDB.update(update_list) - - - self._populate_series() - - self.filtered_dataframe = self._series_points_df[self._series_points_df.index.isin(ids)] - return True - return False - - def isOneGroup(self): - - issel = self._series_points_df.index.isin(self.get_filtered_points().index) - - found_group = False - count = 0 - - for x in issel: - if x: - if not found_group: - found_group=True - count =count+1 - else: - found_group = False - - if count >1: - return False - if count == 1: - return True - - - def flag(self, qualifier_id): - - filtered_points = self.get_filtered_points() - ''' - query = "UPDATE DataValues SET QualifierID = %s WHERE ValueID = ?" % (qualifier_id) - #self._cursor.executemany(query, [(str(x[0]),) for x in filtered_points]) - self._cursor.executemany(query, [(str(x),) for x in filtered_points["ValueID"].astype(int).tolist()]) - ''' - self.memDB.updateFlag(filtered_points.index.tolist(), qualifier_id) - #["ValueID"].astype(int).tolist(), qualifier_id) - - ################### - # Save/Restore - ################### - - def restore(self): - self.memDB.rollback() - - self._populate_series() - self.reset_filter() - - def updateSeries(self, var=None, method=None, qcl=None, is_new_series=False): - """ - - :param var: - :param method: - :param qcl: - :param is_new_series: - :return: - """ - - var_id = var.id if var is not None else None - method_id = method.id if method is not None else None - qcl_id = qcl.id if qcl is not None else None - #self.memDB.changeSeriesIDs(var_id, method_id, qcl_id) - dvs = self.memDB.getDataValuesDF() - if var_id is not None: - dvs["VariableID"] = var_id - if method_id is not None: - dvs["MethodID"] = method_id - if qcl_id is not None: - dvs["QualityControlLevelID"] = qcl_id - - - - #if is new series remove valueids - #if is_new_series: - dvs["ValueID"] = None - ''' - for dv in dvs: - dv.id = None - ''' - - series = self.memDB.series_service.get_series_by_id(self._series_id) - print("original editing series id: %s" % str(series.id)) - - if (var or method or qcl ): - tseries = self.memDB.series_service.get_series_by_id_quint(site_id=int(series.site_id), - var_id=var_id if var else int(series.variable_id), - method_id=method_id if method else int( - series.method_id), - source_id=series.source_id, - qcl_id=qcl_id if qcl else int( - series.quality_control_level_id)) - if tseries: - print("Save existing series ID: %s" % str(series.id)) - series = tseries - else: - print("Series doesn't exist (if you are not, you should be running SaveAs)") - - if is_new_series: - - - series = self.memDB.series_service.copy_series(series) - - - if var: - series.variable_id = var_id - series.variable_code = var.code - series.variable_name = var.name - series.speciation = var.speciation - series.variable_units_id = var.variable_unit_id - series.variable_units_name = var.variable_unit.name - series.sample_medium = var.sample_medium - series.value_type = var.value_type - series.time_support = var.time_support - series.time_units_id = var.time_unit_id - series.time_units_name = var.time_unit.name - series.data_type = var.data_type - series.general_category = var.general_category - - if method: - series.method_id = method_id - series.method_description = method.description - - if qcl: - series.quality_control_level_id = qcl_id - series.quality_control_level_code = qcl.code - ''' - dvs["LocalDateTime"] = pd.to_datetime(dvs["LocalDateTime"]) - dvs["DateTimeUTC"] = pd.to_datetime(dvs["DateTimeUTC"]) - ''' - - - - - - form = "%Y-%m-%d %H:%M:%S" - series.begin_date_time = datetime.datetime.strptime(str(np.min(dvs["LocalDateTime"])), form)#np.min(dvs["LocalDateTime"])#dvs[0].local_date_time - series.end_date_time = datetime.datetime.strptime(str(np.max(dvs["LocalDateTime"])), form)#np.max(dvs["LocalDateTime"])#dvs[-1].local_date_time - series.begin_date_time_utc = datetime.datetime.strptime(str(np.min(dvs["DateTimeUTC"])), form) #dvs[0].date_time_utc - series.end_date_time_utc = datetime.datetime.strptime(str(np.max(dvs["DateTimeUTC"])), form) #dvs[-1].date_time_utc - series.value_count = len(dvs) - - ## Override previous save - if not is_new_series: - # delete old dvs - #pass - self.memDB.series_service.delete_values_by_series(series) - - - #logger.debug("series.data_values: %s" % ([x for x in series.data_values])) - dvs.drop('ValueID', axis=1, inplace=True) - return series, dvs - - def save(self): - """ Save to an existing catalog - :param var: - :param method: - :param qcl: - :return: - """ - - series, dvs = self.updateSeries(is_new_series=False) - if self.memDB.series_service.save_series(series, dvs): - print ("series saved!") - return True - else: - print("The Save was unsuccessful") - return False - - def save_as(self, var=None, method=None, qcl=None): - """ - :param var: - :param method: - :param qcl: - :return: - """ - series, dvs = self.updateSeries(var, method, qcl, is_new_series=True) - - if self.memDB.series_service.save_new_series(series, dvs): - print("series saved!") - return True - else: - print("The Save As Function was Unsuccessful") - return False - - def save_existing(self, var=None, method=None, qcl=None): - """ - :param var: - :param method: - :param qcl: - :return: - """ - series, dvs = self.updateSeries(var, method, qcl, is_new_series=False) - if self.memDB.series_service.save_series(series, dvs): - print("series saved!") - return True - else: - print("The Save As Existing Function was Unsuccessful") - return False - - def create_qcl(self, code, definition, explanation): - return self.memDB.series_service.create_qcl(code, definition, explanation) - - def create_method(self, description, link): - return self.memDB.series_service.create_method(description, link) - - def create_qualifier(self, code, definition): - return self.memDB.series_service.create_qualifier(code, definition) - - def create_variable(self, code, name, speciation, variable_unit_id, sample_medium, - value_type, is_regular, time_support, time_unit_id, data_type, general_category, no_data_value): - - return self.memDB.series_service.create_variable(code, name, speciation, variable_unit_id, sample_medium, - value_type, is_regular, time_support, time_unit_id, data_type, - general_category, no_data_value) - - def reconcile_dates(self, parent_series_id): - # FUTURE FEATURE: pull in new field data from another series and add to this series - # (i.e one series contains new field data of an edited series at a higher qcl) - pass - - diff --git a/odm2api/ODM1_1_1/services/export_service.py b/odm2api/ODM1_1_1/services/export_service.py deleted file mode 100644 index ea65498..0000000 --- a/odm2api/ODM1_1_1/services/export_service.py +++ /dev/null @@ -1,401 +0,0 @@ -import csv -import xml.etree.cElementTree as ET -import datetime - - -class ExportService(): - ''' - Create with the Service Manager!!! - ''' - - def __init__(self, series_service): - self._series_service = series_service - self.dt_format_str = "%m/%d/%Y %I:%M:%S %p" - - def export_series_data(self, series_id, filename, utc=False, site=False, var=False, offset=False, qual=False, - src=False, qcl=False): - series = self._series_service.get_series_by_id(series_id) - if series is None: - return False - - writer = csv.writer(open(filename, 'wb')) - print("filename: ", filename) - self.write_data_header(writer, utc, site, var, offset, qual, src, qcl) - for dv in series.data_values: - self.write_data_row(writer, series, dv, utc, site, var, offset, qual, src, qcl) - - def write_data_row(self, writer, series, dv, utc, site, var, offset, qual, src, qcl): - data = [] - data.append(series.id) - data.append(dv.id) - data.append(dv.data_value) - data.append(dv.value_accuracy) - data.append(dv.local_date_time) - if utc: - data.append(dv.utc_offset) - data.append(dv.date_time_utc) - data.append(series.site_code) - if site: - data.append(series.site_name) - data.append(series.site.type) - data.append(series.site.latitude) - data.append(series.site.longitude) - data.append(series.site.spatial_ref.srs_name) - data.append(series.variable_code) - if var: - data.append(series.variable_name) - data.append(series.speciation) - data.append(series.variable_units_name) - data.append(series.variable.variable_unit.abbreviation) - data.append(series.sample_medium) - data.append(dv.offset_value) - data.append(dv.offset_type_id) - if offset: - if dv.offset_type is not None: - data.append(dv.offset_type.description) - data.append(dv.offset_type.unit.name) - else: - data.append('') - data.append('') - data.append(dv.censor_code) - data.append(dv.qualifier_id) - if qual: - if dv.qualifier is not None: - data.append(dv.qualifier.code) - data.append(dv.qualifier.description) - else: - data.append('') - data.append('') - if src: - data.append(series.organization) - data.append(series.source_description) - data.append(series.citation) - if qcl: - data.append(series.quality_control_level_code) - data.append(series.quality_control_level.definition) - data.append(series.quality_control_level.explanation) - data.append(dv.sample_id) - - writer.writerow(data) - - def write_data_header(self, writer, utc, site, var, offset, qual, src, qcl): - # Build header list - header = [] - header.append("SeriesId") - header.append("ValueId") - header.append("DataValue") - header.append("ValueAccuracy") - header.append("LocalDateTime") - if utc: - header.append("UTCOffset") - header.append("DateTimeUTC") - header.append("SiteCode") - if site: - header.append("SiteName") - header.append("SiteType") - header.append("Latitude") - header.append("Longitude") - header.append("SRSName") - header.append("VariableCode") - if var: - header.append("VariableName") - header.append("Speciation") - header.append("VariableUnitsName") - header.append("VariableUnitsAbbreviation") - header.append("SampleMedium") - header.append("OffsetValue") - header.append("OffsetTypeID") - if offset: - header.append("OffsetDescription") - header.append("OffsetUnitsName") - header.append("CensorCode") - header.append("QualifierID") - if qual: - header.append("QualifierCode") - header.append("QualifierDescription") - if src: - header.append("Organization") - header.append("SourceDescription") - header.append("Citation") - if qcl: - header.append("QualityControlLevelCode") - header.append("Definition") - header.append("Explanation") - header.append("SampleID") - - writer.writerow(header) - - def export_series_metadata(self, series_ids, filename): - if series_ids is None: - return - - root = ET.Element("Metadata") - list_root = ET.SubElement(root, "DataSeriesList") - list_root.set("Total", str(series_ids)) - - try: - with open(filename): - file_exists = True - except IOError: - file_exists = False - - if file_exists: - # Read the file into the XML tree - pass - - if isinstance(series_ids, int): - series = self._series_service.get_series_by_id(series_ids) - self.append_series_node(series, list_root) - else: - for series_id in series_ids: - series = self._series_service.get_series_by_id(series_id) - self.append_series_node(series, list_root) - - tree = ET.ElementTree(root) - tree.write(filename) - - def append_series_node(self, series, parent): - series_node = ET.SubElement(parent, "DataSeries") - series_node.set("ID", str(series.id)) - self.append_general_info(series, series_node) - self.append_site_info(series, series_node) - self.append_var_info(series, series_node) - self.append_method_source_info(series, series_node) - self.append_misc_info(series, series_node) - - return series_node - - def append_general_info(self, series, parent): - meta = series.source.iso_metadata - general_node = ET.SubElement(parent, "GeneralInformation") - topic = ET.SubElement(general_node, "TopicCategory") - topic.text = meta.topic_category - title = ET.SubElement(general_node, "Title") - title.text = meta.title - abstract = ET.SubElement(general_node, "Abstract") - abstract.text = meta.abstract - prof_version = ET.SubElement(general_node, "ProfileVersion") - prof_version.text = meta.profile_version - metadata_link = ET.SubElement(general_node, "MetadataLink") - metadata_link.text = meta.metadata_link - date = ET.SubElement(general_node, "MetadataCreationDate") - # 7/1/2013 12:17:16 PM - date.text = datetime.datetime.now().strftime(self.dt_format_str) - - def append_site_info(self, series, parent): - site = series.site - site_node = ET.SubElement(parent, "SiteInformation") - site_code = ET.SubElement(site_node, "SiteCode") - site_code.text = site.code - site_name = ET.SubElement(site_node, "SiteName") - site_name.text = site.name - site_type = ET.SubElement(site_node, "SiteType") - site_type.text = site.type - - geo_coords = ET.SubElement(site_node, "GeographicCoordinates") - latitude = ET.SubElement(geo_coords, "Latitude") - latitude.text = str(site.latitude) - longitude = ET.SubElement(geo_coords, "Longitude") - longitude.text = str(site.longitude) - srs_id = ET.SubElement(geo_coords, "SRSID") - srs_id.text = str(site.spatial_ref.srs_id) - srs_name = ET.SubElement(geo_coords, "SRSName") - srs_name.text = site.spatial_ref.srs_name - is_geo = ET.SubElement(geo_coords, "IsGeographic") - is_geo.text = str(site.spatial_ref.is_geographic) - notes = ET.SubElement(geo_coords, "Notes") - notes.text = site.spatial_ref.notes - - local_coords = ET.SubElement(site_node, "LocalCoordinates") - local_x = ET.SubElement(local_coords, "LocalX") - local_x.text = str(site.local_x) - local_y = ET.SubElement(local_coords, "LocalY") - local_y.text = str(site.local_y) - local_srs_id = ET.SubElement(local_coords, "SRSID") - local_srs_id.text = str(site.local_spatial_ref.srs_id) - local_srs_name = ET.SubElement(local_coords, "SRSName") - local_srs_name.text = site.local_spatial_ref.srs_name - local_is_geo = ET.SubElement(local_coords, "IsGeographic") - local_is_geo.text = str(site.local_spatial_ref.is_geographic) - local_notes = ET.SubElement(local_coords, "Notes") - local_notes.text = site.local_spatial_ref.notes - elevation = ET.SubElement(local_coords, "Elevation_m") - if site.elevation_m: elevation.text = str(site.elevation_m) - vert_datum = ET.SubElement(local_coords, "VerticalDatum") - if site.vertical_datum_id: vert_datum.text = str(site.vertical_datum_id) - - pos_accuracy = ET.SubElement(site_node, "PosAccuracy_m") - pos_accuracy.text = str(site.pos_accuracy_m) - state = ET.SubElement(site_node, "State") - state.text = site.state - county = ET.SubElement(site_node, "County") - county.text = site.county - comments = ET.SubElement(site_node, "Comments") - comments.text = site.comments - - def append_var_info(self, series, parent): - variable = series.variable - var_node = ET.SubElement(parent, "VariableInformation") - - var_code = ET.SubElement(var_node, "VariableCode") - var_code.text = variable.code - var_name = ET.SubElement(var_node, "VariableName") - var_name.text = variable.name - speciation = ET.SubElement(var_node, "Speciation") - speciation.text = variable.speciation - - var_units = ET.SubElement(var_node, "VariableUnits") - units_name = ET.SubElement(var_units, "UnitsName") - units_name.text = variable.variable_unit.name - units_type = ET.SubElement(var_units, "UnitsType") - units_type.text = variable.variable_unit.type - units_abbrev = ET.SubElement(var_units, "UnitsAbbreviation") - units_abbrev.text = variable.variable_unit.abbreviation - - sample_medium = ET.SubElement(var_node, "SampleMedium") - sample_medium.text = variable.sample_medium - val_type = ET.SubElement(var_node, "ValueType") - val_type.text = variable.value_type - is_reg = ET.SubElement(var_node, "IsRegular") - is_reg.text = str(variable.is_regular) - time_support = ET.SubElement(var_node, "TimeSupport") - time_support.text = str(variable.time_support) - - time_support_units = ET.SubElement(var_node, "TimeSupportUnits") - ts_units_name = ET.SubElement(time_support_units, "UnitsName") - ts_units_name.text = variable.time_unit.name - ts_units_type = ET.SubElement(time_support_units, "UnitsType") - ts_units_type.text = variable.time_unit.type - ts_units_abbrev = ET.SubElement(time_support_units, "UnitsAbbreviation") - ts_units_abbrev.text = variable.time_unit.abbreviation - - data_type = ET.SubElement(var_node, "DataType") - data_type.text = variable.data_type - gen_cat = ET.SubElement(var_node, "GeneralCategory") - gen_cat.text = variable.general_category - no_dv = ET.SubElement(var_node, "NoDataValue") - no_dv.text = str(variable.no_data_value) - - period = ET.SubElement(var_node, "PeriodOfRecord") - begin_dt = ET.SubElement(period, "BeginDateTime") - begin_dt.text = series.begin_date_time.strftime(self.dt_format_str) - end_dt = ET.SubElement(period, "EndDateTime") - end_dt.text = series.end_date_time.strftime(self.dt_format_str) - begin_dt_utc = ET.SubElement(period, "BeginDateTimeUTC") - begin_dt_utc.text = series.begin_date_time_utc.strftime(self.dt_format_str) - end_dt_utc = ET.SubElement(period, "EndDateTimeUTC") - end_dt_utc.text = series.end_date_time_utc.strftime(self.dt_format_str) - value_count = ET.SubElement(period, "ValueCount") - value_count.text = str(series.value_count) - - def append_method_source_info(self, series, parent): - method = series.method - method_node = ET.SubElement(parent, "MethodInformation") - method_desc = ET.SubElement(method_node, "MethodDescription") - method_desc.text = method.description - method_link = ET.SubElement(method_node, "MethodLink") - method_link.text = method.link - - source = series.source - source_node = ET.SubElement(parent, "SourceInformation") - org = ET.SubElement(source_node, "Organization") - org.text = source.organization - source_desc = ET.SubElement(source_node, "SourceDescription") - source_desc.text = source.description - source_link = ET.SubElement(source_node, "SourceLink") - source_link.text = source.link - - contact = ET.SubElement(source_node, "Contact") - contact_name = ET.SubElement(contact, "ContactName") - contact_name.text = source.contact_name - phone = ET.SubElement(contact, "Phone") - phone.text = source.phone - email = ET.SubElement(contact, "Email") - email.text = source.email - address = ET.SubElement(contact, "Address") - address.text = source.address - city = ET.SubElement(contact, "City") - city.text = source.city - state = ET.SubElement(contact, "State") - state.text = source.state - zip_code = ET.SubElement(contact, "ZipCode") - zip_code.text = source.zip_code - - citation = ET.SubElement(source_node, "Citation") - citation.text = source.citation - - def append_misc_info(self, series, parent): - qcl = series.quality_control_level - - qcl_node = ET.SubElement(parent, "QualityControlLevelInformation") - qcl_code = ET.SubElement(qcl_node, "QualityControlLevelCode") - qcl_code.text = qcl.code - qcl_def = ET.SubElement(qcl_node, "Definition") - qcl_def.text = qcl.definition - qcl_expl = ET.SubElement(qcl_node, "Explanation") - qcl_expl.text = qcl.explanation - - offsets_node = ET.SubElement(parent, "OffsetInformation") - offsets = self._series_service.get_offset_types_by_series_id(series.id) - for offset in offsets: - offset_id = ET.SubElement(offsets_node, "Offset") - if offset: - offset_id.set("ID", str(offset.id)) - else: - offset_id.set("ID", "") - offset_desc = ET.SubElement(offsets_node, "OffsetDescription") - if offset: offset_desc.text = offset.description - offset_units = ET.SubElement(offsets_node, "OffsetUnits") - units_name = ET.SubElement(offset_units, "UnitsName") - if offset: units_name.text = offset.unit.name - units_type = ET.SubElement(offset_units, "UnitsType") - if offset: units_type.text = offset.unit.type - units_abbrev = ET.SubElement(offset_units, "UnitsAbbreviation") - if offset: units_abbrev.text = offset.unit.abbreviation - - qualifiers_node = ET.SubElement(parent, "QualifierInformation") - qualifiers = self._series_service.get_qualifiers_by_series_id(series.id) - for qual in qualifiers: - qual_id = ET.SubElement(qualifiers_node, "Qualifier") - if qual: - qual_id.set("ID", str(qual.id)) - else: - qual_id.set("ID", "") - qual_code = ET.SubElement(qual_id, "QualiferCode") - if qual: qual_code.text = qual.code - qual_desc = ET.SubElement(qual_id, "QualifierDescription") - if qual: qual_desc.text = qual.description - - samples_node = ET.SubElement(parent, "SampleInformation") - samples = self._series_service.get_samples_by_series_id(series.id) - for sample in samples: - sample_id = ET.SubElement(samples_node, "Sample") - if sample: - sample_id.set("ID", str(sample.id)) - else: - sample_id.set("ID", "") - sample_type = ET.SubElement(sample_id, "SampleType") - if sample: sample_type.text = sample.type - lab_code = ET.SubElement(sample_id, "LabSampleCode") - if sample: lab_code.text = sample.lab_sample_code - lab_method_id = ET.SubElement(sample_id, "LabMethodID") - if sample: lab_method_id = sample.lab_method_id - - lab_method_node = ET.SubElement(parent, "LabMethodInformation") - for sample in samples: - if sample: lab_method = sample.lab_method - lab_method_id = ET.SubElement(lab_method_node, "LabMethod") - if lab_method: - lab_method_id.set("ID", str(lab_method.id)) - else: - lab_method_id.set("ID", "") - lab_name = ET.SubElement(lab_method_id, "LabName") - if lab_method: lab_name.text = lab_method.name - lab_org = ET.SubElement(lab_method_id, "LabOrganization") - if lab_method: lab_org.text = lab_method.organization - method_name = ET.SubElement(lab_method_id, "LabMethodName") - if lab_method: method_name.text = lab_method.method_name - method_desc = ET.SubElement(lab_method_id, "LabMethodDescription") - if lab_method: method_desc.text = lab_method.method_description - method_link = ET.SubElement(lab_method_id, "LabMethodLink") - if lab_method: method_link.text = lab_method.link \ No newline at end of file diff --git a/odm2api/ODM1_1_1/services/series_service.py b/odm2api/ODM1_1_1/services/series_service.py deleted file mode 100644 index e880831..0000000 --- a/odm2api/ODM1_1_1/services/series_service.py +++ /dev/null @@ -1,886 +0,0 @@ -import logging - - -from sqlalchemy import distinct, func, not_ - - -from ...base import serviceBase -import pandas as pd - - -import odm2api.ODM1_1_1.models as ODM1 -import odm2api.ODM2.LikeODM1.models as ODM2 - -#Set Default -global ODM -ODM = ODM1 - - - -class SeriesService(serviceBase): - # Accepts a string for creating a SessionFactory, default uses odmdata/connection.cfg - - def refreshDB(self, ver): - self._version= ver - if ver == 1.1: - #global ODM - ODM = ODM1 - elif ver == 2.0: - #global ODM - ODM = ODM2 - else: - #global ODM - ODM = ODM1 - - def reset_session(self): - self._session = self._session_factory.getSession() # Reset the session in order to prevent memory leaks - - # def get_db_version(self): - # return self._session.query(ODM.ODMVersion).first().version_number - -##################### -# -# Get functions -# -##################### - - # Site methods - def get_all_sites(self): - """ - - :return: List[Sites] - """ - return self._session.query(ODM.Site).order_by(ODM.Site.code).all() - - def get_used_sites(self): - """ - Return a list of all sites that are being referenced in the Series Catalog Table - :return: List[Sites] - """ - try: - site_ids = [x[0] for x in self._session.query(distinct(ODM.Series.site_id)).all()] - except: - site_ids = None - - if not site_ids: - return None - - Sites = [] - for site_id in site_ids: - Sites.append(self._session.query(ODM.Site).filter_by(id=site_id).first()) - - return Sites - - - def get_site_by_id(self, site_id): - """ - return a Site object that has an id=site_id - :param site_id: integer- the identification number of the site - :return: Sites - """ - try: - return self._session.query(ODM.Site).filter_by(id=site_id).first() - except: - return None - - # Variables methods - def get_used_variables(self): - """ - #get list of used variable ids - :return: List[Variables] - """ - - try: - var_ids = [x[0] for x in self._session.query(distinct(ODM.Series.variable_id)).all()] - except: - var_ids = None - - if not var_ids: - return None - - Variables = [] - - #create list of variables from the list of ids - for var_id in var_ids: - Variables.append(self._session.query(ODM.Variable).filter_by(id=var_id).first()) - - return Variables - - def get_all_variables(self): - """ - - :return: List[Variables] - """ - return self._session.query(ODM.Variable).all() - - def get_variable_by_id(self, variable_id): - """ - - :param variable_id: int - :return: Variables - """ - try: - return self._session.query(ODM.Variable).filter_by(id=variable_id).first() - except: - return None - - def get_variable_by_code(self, variable_code): - """ - - :param variable_code: str - :return: Variables - """ - try: - return self._session.query(ODM.Variable).filter_by(code=variable_code).first() - except: - return None - - def get_variables_by_site_code(self, site_code): # covers NoDV, VarUnits, TimeUnits - """ - Finds all of variables at a site - :param site_code: str - :return: List[Variables] - """ - try: - var_ids = [x[0] for x in self._session.query(distinct(ODM.Series.variable_id)).filter_by( - site_code=site_code).all()] - except: - var_ids = None - - variables = [] - for var_id in var_ids: - variables.append(self._session.query(ODM.Variable).filter_by(id=var_id).first()) - - return variables - - # Unit methods - def get_all_units(self): - """ - - :return: List[Units] - """ - return self._session.query(ODM.Unit).all() - - def get_unit_by_name(self, unit_name): - """ - - :param unit_name: str - :return: Units - """ - try: - return self._session.query(ODM.Unit).filter_by(name=unit_name).first() - except: - return None - - def get_unit_by_id(self, unit_id): - """ - - :param unit_id: int - :return: Units - """ - try: - return self._session.query(ODM.Unit).filter_by(id=unit_id).first() - except: - return None - - def get_all_qualifiers(self): - """ - - :return: List[Qualifiers] - """ - result = self._session.query(ODM.Qualifier).order_by(ODM.Qualifier.code).all() - return result - - def get_qualifiers_by_series_id(self, series_id): - """ - - :param series_id: - :return: - """ - subquery = self._session.query(ODM.DataValue.qualifier_id).outerjoin( - ODM.Series.data_values).filter(ODM.Series.id == series_id, ODM.DataValue.qualifier_id != None).distinct().subquery() - return self._session.query(ODM.Qualifier).join(subquery).distinct().all() - - #QCL methods - def get_all_qcls(self): - return self._session.query(ODM.QualityControlLevel).all() - - def get_qcl_by_id(self, qcl_id): - try: - return self._session.query(ODM.QualityControlLevel).filter_by(id=qcl_id).first() - except: - return None - - def get_qcl_by_code(self, qcl_code): - try: - return self._session.query(ODM.QualityControlLevel).filter_by(code=qcl_code).first() - except: - return None - - # Method methods - def get_all_methods(self): - return self._session.query(ODM.Method).all() - - def get_method_by_id(self, method_id): - try: - result = self._session.query(ODM.Method).filter_by(id=method_id).first() - except: - result = None - return result - - def get_method_by_description(self, method_code): - try: - result = self._session.query(ODM.Method).filter_by(description=method_code).first() - except: - result = None - return result - - def get_offset_types_by_series_id(self, series_id): - """ - - :param series_id: - :return: - """ - subquery = self._session.query(ODM.DataValue.offset_type_id).outerjoin( - ODM.Series.data_values).filter(ODM.Series.id == series_id, ODM.DataValue.offset_type_id != None).distinct().subquery() - return self._session.query(ODM.OffsetType).join(subquery).distinct().all() - - def get_samples_by_series_id(self, series_id): - """ - - :param series_id: - :return: - """ - - subquery = self._session.query(ODM.DataValue.sample_id).outerjoin(ODM.Series.data_values).filter(ODM.Series.id == series_id, ODM.DataValue.sample_id != None).distinct().subquery() - return self._session.query(ODM.Sample).join(subquery).distinct().all() - - # Series Catalog methods - def get_all_series(self): - """ - Returns all series as a modelObject - :return: List[Series] - """ - - #logger.debug("%s" % self._session.query(Series).order_by(Series.id).all()) - return self._session.query(ODM.Series).order_by(ODM.Series.id).all() - - def get_series_by_site(self , site_id): - """ - - :param site_id: int - :return: List[Series] - """ - try: - selectedSeries = self._session.query(ODM.Series).filter_by(site_id=site_id).order_by(ODM.Series.id).all() - return selectedSeries - except: - return None - - def get_series_by_id(self, series_id): - """ - - :param series_id: int - :return: Series - """ - try: - return self._session.query(ODM.Series).filter_by(id=series_id).first() - except Exception as e: - print(e) - return None - - def get_series_by_id_quint(self, site_id, var_id, method_id, source_id, qcl_id): - """ - - :param site_id: - :param var_id: - :param method_id: - :param source_id: - :param qcl_id: - :return: Series - """ - try: - return self._session.query(ODM.Series).filter_by( - site_id=site_id, variable_id=var_id, method_id=method_id, - source_id=source_id, quality_control_level_id=qcl_id).first() - except: - return None - - def get_series_from_filter(self): - # Pass in probably a Series object, match it against the database - pass - - # Data Value Methods - def get_values_by_series(self, series_id): - ''' - - :param series_id: Series id - :return: pandas dataframe - ''' - series= self.get_series_by_id(series_id) - if series: - q = self._session.query(ODM.DataValue).filter_by( - site_id=series.site_id, - variable_id=series.variable_id, - method_id=series.method_id, - source_id=series.source_id, - quality_control_level_id=series.quality_control_level_id) - - query=q.statement.compile(dialect=self._session_factory.engine.dialect) - data= pd.read_sql_query(sql= query, - con = self._session_factory.engine, - params = query.params ) - #return data.set_index(data['LocalDateTime']) - return data - else: - return None - - def get_all_values_df(self): - """ - - :return: Pandas DataFrame object - """ - q = self._session.query(ODM.DataValue).order_by(ODM.DataValue.local_date_time) - query = q.statement.compile(dialect=self._session_factory.engine.dialect) - data = pd.read_sql_query(sql=query, con=self._session_factory.engine, - params=query.params) - columns = list(data) - - columns.insert(0, columns.pop(columns.index("DataValue"))) - columns.insert(1, columns.pop(columns.index("LocalDateTime"))) - columns.insert(2, columns.pop(columns.index("QualifierID"))) - - data = data.ix[:, columns] - return data.set_index(data['LocalDateTime']) - - def get_all_values_list(self): - """ - - :return: - """ - result = self._session.query(ODM.DataValue).order_by(ODM.DataValue.local_date_time).all() - return [x.list_repr() for x in result] - - def get_all_values(self): - return self._session.query(ODM.DataValue).order_by(ODM.DataValue.local_date_time).all() - - @staticmethod - def calcSeason(row): - - month = int(row["Month"]) - - if month in [1, 2, 3]: - return 1 - elif month in[4, 5, 6]: - return 2 - elif month in [7, 8, 9]: - return 3 - elif month in [10, 11, 12]: - return 4 - - def get_all_plot_values(self): - """ - - :return: - """ - q = self._session.query(ODM.DataValue.data_value.label('DataValue'), - ODM.DataValue.local_date_time.label('LocalDateTime'), - ODM.DataValue.censor_code.label('CensorCode'), - func.strftime('%m', ODM.DataValue.local_date_time).label('Month'), - func.strftime('%Y',ODM.DataValue.local_date_time).label('Year') - #DataValue.local_date_time.strftime('%m'), - #DataValue.local_date_time.strftime('%Y')) - ).order_by(ODM.DataValue.local_date_time) - query = q.statement.compile(dialect=self._session_factory.engine.dialect) - data = pd.read_sql_query(sql=query, - con=self._session_factory.engine, - params=query.params) - data["Season"] = data.apply(self.calcSeason, axis=1) - return data.set_index(data['LocalDateTime']) - - def get_plot_values(self, seriesID, noDataValue, startDate = None, endDate = None ): - """ - - :param seriesID: - :param noDataValue: - :param startDate: - :param endDate: - :return: - """ - series = self.get_series_by_id(seriesID) - values = self.get_values_by_series(seriesID) - - DataValues = [ - (dv.data_value, dv.local_date_time, dv.censor_code, dv.local_date_time.strftime('%m'), - dv.local_date_time.strftime('%Y')) - for dv in values - if dv.data_value != noDataValue if dv.local_date_time >= startDate if dv.local_date_time <= endDate - ] - data = pd.DataFrame(DataValues, columns=["DataValue", "LocalDateTime", "CensorCode", "Month", "Year"]) - data.set_index(data['LocalDateTime'], inplace=True) - data["Season"] = data.apply(self.calcSeason, axis=1) - return data - - - - def get_data_value_by_id(self, id): - """ - - :param id: - :return: - """ - try: - return self._session.query(ODM.DataValue).filter_by(id=id).first() - except: - return None - - def get_all_sources(self): - try: - return self._session.query(ODM.Source).all() - except: - return None - - -##################### -# -#Update functions -# -##################### - def update_series(self, series): - """ - - :param series: - :return: - """ - merged_series = self._session.merge(series) - self._session.add(merged_series) - self._session.commit() - - def update_dvs(self, dv_list): - """ - - :param dv_list: - :return: - """ - merged_dv_list = map(self._session.merge, dv_list) - self._session.add_all(merged_dv_list) - self._session.commit() - -##################### -# -#Create functions -# -##################### - def save_series(self, series, dvs): - """ Save to an Existing Series - :param series: - :param data_values: - :return: - """ - - if self.series_exists(series): - - try: - self._session.add(series) - self._session.commit() - self.save_values(dvs) - except Exception as e: - self._session.rollback() - raise e - #logger.debug("Existing File was overwritten with new information") - return True - else: - #logger.debug("There wasn't an existing file to overwrite, please select 'Save As' first") - # there wasn't an existing file to overwrite - raise Exception("Series does not exist, unable to save. Please select 'Save As'") - - def save_new_series(self, series, dvs): - """ Create as a new catalog entry - :param series: - :param data_values: - :return: - """ - # Save As case - if self.series_exists(series): - msg = "There is already an existing file with this information. Please select 'Save' or 'Save Existing' to overwrite" - #logger.debug(msg) - raise Exception(msg) - else: - try: - self._session.add(series) - self._session.commit() - self.save_values(dvs) - #self._session.add_all(dvs) - except Exception as e: - self._session.rollback() - raise e - - #logger.debug("A new series was added to the database, series id: "+str(series.id)) - return True - - def save_values(self, values): - """ - - :param values: pandas dataframe - :return: - """ - values.to_sql(name="datavalues", if_exists='append', con=self._session_factory.engine, index=False) - - def create_new_series(self, data_values, site_id, variable_id, method_id, source_id, qcl_id): - """ - - :param data_values: - :param site_id: - :param variable_id: - :param method_id: - :param source_id: - :param qcl_id: - :return: - """ - self.update_dvs(data_values) - series = ODM.Series() - series.site_id = site_id - series.variable_id = variable_id - series.method_id = method_id - series.source_id = source_id - series.quality_control_level_id = qcl_id - - self._session.add(series) - self._session.commit() - return series - - def create_method(self, description, link=None): - """ - - :param description: - :param link: - :return: - """ - meth = ODM.Method() - meth.description = description - if link is not None: - meth.link = link - - self._session.add(meth) - self._session.commit() - return meth - - def create_variable_by_var(self, var): - """ - - :param var: Variable Object - :return: - """ - try: - self._session.add(var) - self._session.commit() - return var - except: - return None - - def create_variable( - self, code, name, speciation, variable_unit_id, sample_medium, - value_type, is_regular, time_support, time_unit_id, data_type, - general_category, no_data_value): - """ - - :param code: - :param name: - :param speciation: - :param variable_unit_id: - :param sample_medium: - :param value_type: - :param is_regular: - :param time_support: - :param time_unit_id: - :param data_type: - :param general_category: - :param no_data_value: - :return: - """ - var = ODM.Variable() - var.code = code - var.name = name - var.speciation = speciation - var.variable_unit_id = variable_unit_id - var.sample_medium = sample_medium - var.value_type = value_type - var.is_regular = is_regular - var.time_support = time_support - var.time_unit_id = time_unit_id - var.data_type = data_type - var.general_category = general_category - var.no_data_value = no_data_value - - self._session.add(var) - self._session.commit() - return var - - def create_qcl(self, code, definition, explanation): - """ - - :param code: - :param definition: - :param explanation: - :return: - """ - qcl = ODM.QualityControlLevel() - qcl.code = code - qcl.definition = definition - qcl.explanation = explanation - - self._session.add(qcl) - self._session.commit() - return qcl - - def create_qualifier_by_qual(self, qualifier): - self._session.add(qualifier) - self._session.commit() - return qualifier - - def create_qualifier(self, code, description): - """ - - :param code: - :param description: - :return: - """ - qual = ODM.Qualifier() - qual.code = code - qual.description = description - - return self.create_qualifier_by_qual(qual) - -##################### -# -# Delete functions -# -##################### - - def delete_series(self, series): - """ - - :param series: - :return: - """ - self.delete_values_by_series(series) - - delete_series = self._session.merge(series) - self._session.delete(delete_series) - self._session.commit() - - def delete_values_by_series(self, series): - """ - - :param series: - :return: - """ - try: - return self._session.query(ODM.DataValue).filter_by(site_id = series.site_id, - variable_id = series.variable_id, - method_id = series.method_id, - source_id = series.source_id, - quality_control_level_id = series.quality_control_level_id).delete() - except: - return None - - def delete_dvs(self, id_list): - """ - - :param id_list: list of ids - :return: - """ - self._session.query(ODM.DataValue).filter(ODM.DataValue.id.in_(id_list)).delete(False) - -##################### -# -#Exist functions -# -##################### - - - def series_exists(self, series): - """ - - :param series: - :return: - """ - return self.series_exists_quint( - series.site_id, - series.variable_id, - series.method_id, - series.source_id, - series.quality_control_level_id - ) - - def series_exists_quint(self, site_id, var_id, method_id, source_id, qcl_id): - """ - - :param site_id: - :param var_id: - :param method_id: - :param source_id: - :param qcl_id: - :return: - """ - try: - result = self._session.query(ODM.Series).filter_by( - site_id=site_id, - variable_id=var_id, - method_id=method_id, - source_id=source_id, - quality_control_level_id=qcl_id - ).one() - - return True - except: - return False - - def qcl_exists(self, q): - """ - - :param q: - :return: - """ - try: - result = self._session.query(ODM.QualityControlLevel).filter_by(code=q.code, definition=q.definition).one() - return True - except: - - return False - - def method_exists(self, m): - """ - - :param m: - :return: - """ - try: - result = self._session.query(ODM.Method).filter_by(description=m.description).one() - return True - except: - return False - - def variable_exists(self, v): - """ - - :param v: - :return: - """ - try: - result = self._session.query(ODM.Variable).filter_by(code=v.code, - name=v.name, speciation=v.speciation, - variable_unit_id=v.variable_unit_id, - sample_medium=v.sample_medium, - value_type=v.value_type, is_regular=v.is_regular, - time_support=v.time_support, - time_unit_id=v.time_unit_id, data_type=v.data_type, - general_category=v.general_category, - no_data_value=v.no_data_value).one() - return result - except: - return None - - -####CV_Service - - def get_vertical_datum_cvs(self): - result = self._session.query(ODM.VerticalDatumCV).order_by(ODM.VerticalDatumCV.term).all() - return result - - def get_samples(self): - result = self._session.query(ODM.Sample).order_by(ODM.Sample.lab_sample_code).all() - return result - - def get_site_type_cvs(self): - result = self._session.query(ODM.SiteTypeCV).order_by(ODM.SiteTypeCV.term).all() - return result - - def get_variable_name_cvs(self): - result = self._session.query(ODM.VariableNameCV).order_by(ODM.VariableNameCV.term).all() - return result - - def get_offset_type_cvs(self): - result = self._session.query(ODM.OffsetType).order_by(ODM.OffsetType.id).all() - return result - - def get_speciation_cvs(self): - result = self._session.query(ODM.SpeciationCV).order_by(ODM.SpeciationCV.term).all() - return result - - def get_sample_medium_cvs(self): - result = self._session.query(ODM.SampleMediumCV).order_by(ODM.SampleMediumCV.term).all() - return result - - def get_value_type_cvs(self): - result = self._session.query(ODM.ValueTypeCV).order_by(ODM.ValueTypeCV.term).all() - return result - - def get_data_type_cvs(self): - result = self._session.query(ODM.DataTypeCV).order_by(ODM.DataTypeCV.term).all() - return result - - def get_general_category_cvs(self): - result = self._session.query(ODM.GeneralCategoryCV).order_by(ODM.GeneralCategoryCV.term).all() - return result - - def get_censor_code_cvs(self): - result = self._session.query(ODM.CensorCodeCV).order_by(ODM.CensorCodeCV.term).all() - return result - - def get_sample_type_cvs(self): - result = self._session.query(ODM.SampleTypeCV).order_by(ODM.SampleTypeCV.term).all() - return result - - def get_units(self): - result = self._session.query(ODM.Unit).all() - return result - - def get_units_not_uni(self): - result = self._session.query(ODM.Unit).filter(not_(ODM.Unit.name.contains('angstrom'))).all() - return result - - def get_units_names(self): - result = self._session.query(ODM.Unit.name).all() - return result - - # return a single cv - def get_unit_by_name(self, unit_name): - result = self._session.query(ODM.Unit).filter_by(name=unit_name).first() - return result - - def get_unit_by_id(self, unit_id): - result = self._session.query(ODM.Unit).filter_by(id=unit_id).first() - return result - - def copy_series(from_series): - new = ODM.Series() - new.site_id = from_series.site_id - new.site_code = from_series.site_code - new.site_name = from_series.site_name - new.variable_id = from_series.variable_id - new.variable_code = from_series.variable_code - new.variable_name = from_series.variable_name - new.speciation = from_series.speciation - new.variable_units_id = from_series.variable_units_id - new.variable_units_name = from_series.variable_units_name - new.sample_medium = from_series.sample_medium - new.value_type = from_series.value_type - new.time_support = from_series.time_support - new.time_units_id = from_series.time_units_id - new.time_units_name = from_series.time_units_name - new.data_type = from_series.data_type - new.general_category = from_series.general_category - new.method_id = from_series.method_id - new.method_description = from_series.method_description - new.source_id = from_series.source_id - new.source_description = from_series.source_description - new.organization = from_series.organization - new.citation = from_series.citation - new.quality_control_level_id = from_series.quality_control_level_id - new.quality_control_level_code = from_series.quality_control_level_code - new.begin_date_time = from_series.begin_date_time - new.begin_date_time_utc = from_series.begin_date_time_utc - new.end_date_time_utc = from_series.end_date_time_utc - new.value_count = from_series.value_count - return new diff --git a/odm2api/ODM2/LikeODM1/__init__.py b/odm2api/ODM2/LikeODM1/__init__.py deleted file mode 100644 index 426015b..0000000 --- a/odm2api/ODM2/LikeODM1/__init__.py +++ /dev/null @@ -1,66 +0,0 @@ - -'''from model import CensorCodeCV -from model import DataTypeCV -from model import DataValue -from model import GeneralCategoryCV -from model import ISOMetadata -from model import LabMethod -from model import Method -from model import ODMVersion -from model import OffsetType -from model import Qualifier -from model import QualityControlLevel -from model import Sample -from model import SampleMediumCV -from sample_type_cv import SampleTypeCV -from series import Series -from session_factory import SessionFactory -from site import Site -from site_type_cv import SiteTypeCV -from source import Source -from spatial_reference import SpatialReference -from speciation_cv import SpeciationCV -from topic_category_cv import TopicCategoryCV -from unit import Unit -from value_type_cv import ValueTypeCV -from variable import Variable -from variable_name_cv import VariableNameCV -from vertical_datum_cv import VerticalDatumCV -from memory_database import MemoryDatabase - -from series import copy_series -from data_value import copy_data_value -''' -import models - -__all__ = [ - 'Base', - 'CensorCodeCV', - 'DataTypeCV', - 'DataValue', - 'GeneralCategoryCV', - 'ISOMetadata', - 'LabMethod', - 'Method', - 'ODMVersion', - 'OffsetType', - 'Qualifier', - 'QualityControlLevel', - 'Sample', - 'SampleMediumCV', - 'SampleTypeCV', - 'Series', - 'SessionFactory', - 'Site', - 'SiteTypeCV', - 'Source', - 'SpatialReference', - 'SpeciationCV', - 'TopicCategoryCV', - 'Unit', - 'ValueTypeCV', - 'Variable', - 'VariableNameCV', - 'VerticalDatumCV', - -] \ No newline at end of file diff --git a/odm2api/ODM2/LikeODM1/models.py b/odm2api/ODM2/LikeODM1/models.py deleted file mode 100644 index 6fb2f32..0000000 --- a/odm2api/ODM2/LikeODM1/models.py +++ /dev/null @@ -1,730 +0,0 @@ -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import column_property, relationship -from sqlalchemy import select, MetaData, Integer, String, Column, ForeignKey - -Base = declarative_base() - -metadata = MetaData() - -################ODM 2 Tables########### - -from ...ODM2.models import Actions, ActionBy, Organizations, Affiliations, People, \ - SamplingFeatures, Results, Variables, Methods, TimeSeriesResults, \ - TimeSeriesResultValues, Sites, FeatureActions, ProcessingLevels - - -action_table = Actions() - -# ################################################################################### -# Monitoring Site Locations -# ################################################################################### - - -class SpatialReference(Base): - __tablename__ = u'spatialreferences' - __table_args__ = {u'schema': 'odm2'} - - id = Column('spatialreferenceid', Integer, primary_key=True) - srs_id = Column('srsid', String) - srs_name = Column('srsname', String) - is_geographic = None - # is_geographic = Column('IsGeographic', Boolean) - notes = Column('description', String) - - def __repr__(self): - return "" % (self.id, self.srs_name) - - -sf_table = SamplingFeatures().__table__ -site_table = Sites().__table__ - -site_table = select([ - site_table.c.samplingfeatureid, - site_table.c.spatialreferenceid.label('sitespatialreferenceid'), - site_table.c.latitude, - site_table.c.longitude, - site_table.c.sitetypecv, -]).alias("odm2_sites") - -site_join = site_table.join(sf_table, site_table.c.samplingfeatureid == sf_table.c.samplingfeatureid) - - -class Site(Base): - __tablename__ = u'sites' - - __table__ = site_join - - id = site_join.c.odm2_sites_samplingfeatureid - code = site_join.c.odm2_samplingfeatures_samplingfeaturecode - name = site_join.c.odm2_samplingfeatures_samplingfeaturename - latitude = site_join.c.odm2_sites_latitude - longitude = site_join.c.odm2_sites_longitude - lat_long_datum_id = site_join.c.odm2_sites_sitespatialreferenceid # ._clone().foreign_keys = ForeignKey("SpatialReference.id")#, Integer, ForeignKey("SpatialReference.id"))#column_property(site_table.c.LatLonDatumID, ForeignKey('SpatialReference.id')) - elevation_m = site_join.c.odm2_samplingfeatures_elevation_m - vertical_datum_id = site_join.c.odm2_samplingfeatures_elevationdatumcv - - local_x = None - local_y = None - local_projection_id = None # Column('LocalProjectionID', Integer, ForeignKey('SpatialReferences.SpatialReferenceID')) - pos_accuracy_m = None - state = None - county = None - comments = None - - # relationships - # TODO @sreeder, Please take a look at this line as it throws: sqlalchemy.exc.InvalidRequestError: Class does not have a mapped column named 'lat_long_datum_id' - # :) - # spatial_ref = relationship(SpatialReference, primaryjoin=("SpatialReference.id==Site2.lat_long_datum_id")) - # spatial_ref = relationship(SpatialReference) - # spatial_ref = relationship(SpatialReference, primaryjoin="Site.lat_long_datum_id == SpatialReference.id") - - def __repr__(self): - return "" % (self.code, self.name, self.elevation_m) - - -# ################################################################################### -# Units -# ################################################################################### - -class Unit(Base): - __tablename__ = u'units' - __table_args__ = {u'schema': 'odm2'} - - id = Column('unitsid', Integer, primary_key=True) - name = Column('unitsname', String) - type = Column('unitstypecv', String) - abbreviation = Column('unitsabbreviation', String) - - def __repr__(self): - return "" % (self.id, self.name, self.type, self.abbreviation) - -# ################################################################################### -# Variables -# ################################################################################### - -"""Requires joining with Variable, Result, and Timeseriesresult to build Variable for ODM1_1_1""" - -variables_table = Variables().__table__ -ts_table = TimeSeriesResults().__table__ - -result_table = Results.__table__ -result_aliased_table = select([ - result_table.c.resultid.label("RID"), - result_table.c.unitsid, - result_table.c.variableid, - result_table.c.sampledmediumcv, - result_table.c.featureactionid.label("FAID"), - result_table.c.processinglevelid, - result_table.c.valuecount, -]).alias("odm2_results") - -ts_join = result_aliased_table.join(ts_table, result_aliased_table.c.RID == ts_table.c.resultid) -variable_join = ts_join.join(variables_table, variables_table.c.variableid == ts_join.c.odm2_results_RID) - - -class Variable(Base): - __table__ = variable_join - __tablename__ = u'variables' - - id = variable_join.c.odm2_variables_variableid # Column('VariableID', Integer, primary_key=True) - code = variable_join.c.odm2_variables_variablecode # Column('VariableCode', String, nullable=False) - name = variable_join.c.odm2_variables_variablenamecv # Column('VariableNameCV', String, nullable=False) - speciation = variable_join.c.odm2_variables_speciationcv # Column('SpeciationCV', String, nullable=False) - no_data_value = variable_join.c.odm2_variables_nodatavalue # Column('NoDataValue', Float, nullable=False) - - variable_unit_id = variable_join.c.odm2_results_unitsid # Column('VariableUnitsID', Integer, ForeignKey('Units.UnitsID'), nullable=False) - sample_medium = variable_join.c.odm2_results_sampledmediumcv # Column('ODM2_Results_UnitsID', String, nullable=False) - value_type = variable_join.c.odm2_variables_variabletypecv # Column('ValueType', String, nullable=False) - is_regular = None # Column('IsRegular', Boolean, nullable=False) - time_support = variable_join.c.odm2_timeseriesresults_intendedtimespacing # Column('TimeSupport', Float, nullable=False) - time_unit_id = variable_join.c.odm2_timeseriesresults_intendedtimespacingunitsid # Column('TimeUnitsID', Integer, ForeignKey('Units.UnitsID'), nullable=False) - data_type = variable_join.c.odm2_timeseriesresults_aggregationstatisticcv # Column('DataType', String, nullable=False) - general_category = None # Column('GeneralCategory', String, nullable=False) - - """ - # relationships - variable_unit = relationship(Unit, primaryjoin=( - "Unit.id==Variable.variable_unit_id")) # <-- Uses class attribute names, not table column names - time_unit = relationship(Unit, primaryjoin=("Unit.id==Variable.time_unit_id")) - """ - - def __repr__(self): - return "" % \ - (self.id, self.code, self.name, self.speciation, self.no_data_value, self.variable_unit_id, - self.sample_medium, self.value_type, self.time_support, self.time_unit_id, self.data_type) - - -# ################################################################################### -# Data Sources -# ################################################################################### - - -affiliation_table = Affiliations().__table__ -affiliation_table = select([ - affiliation_table.c.affiliationid, - affiliation_table.c.organizationid.label("affiliationorgid"), - affiliation_table.c.primaryphone, - affiliation_table.c.primaryemail, - affiliation_table.c.primaryaddress -]).alias("odm2_affiliations") - -organization_table = Organizations().__table__ - -people_table = People().__table__ -people_aliased_table = select([ - people_table.c.personid.label("PID"), - people_table.c.personfirstname, - people_table.c.personmiddlename, - people_table.c.personlastname, -]).alias("odm2_people") - -affiliation_join = people_aliased_table.join(affiliation_table, people_aliased_table.c.PID == - affiliation_table.c.affiliationid) -source_join = affiliation_join.join(organization_table, affiliation_join.c.odm2_affiliations_affiliationorgid == - organization_table.c.organizationid) - - -class Source(Base): - __table__ = source_join - __tablename__ = u'datasources' - __table_args__ = {u'schema': u'odm2'} - - id = source_join.c.odm2_affiliations_affiliationid # Column('OrganizationID', Integer, primary_key=True) - organization = source_join.c.odm2_affiliations_affiliationorgid # Column('OrganizationName', String, nullable=False) - description = source_join.c.odm2_organizations_organizationdescription # Column('OrganizationDescription', String, nullable=False) - link = source_join.c.odm2_organizations_organizationlink # Column('OrganizationLink', String) - - first_name = source_join.c.odm2_people_personfirstname - middle_name = source_join.c.odm2_people_personmiddlename - last_name = source_join.c.odm2_people_personlastname - # this doesnt work... - # contact_name = column_property(first_name + " " + middle_name + " " + last_name) - contact_name = column_property(first_name + " " + last_name) - - phone = source_join.c.odm2_affiliations_primaryphone # Column('Phone', String, nullable=False) - email = source_join.c.odm2_affiliations_primaryemail # Column('Email', String, nullable=False) - address = source_join.c.odm2_affiliations_primaryaddress # Column('Address', String, nullable=False) - - @property - def city(self): - return "Unknown" - - @property - def state(self): - return "Unknown" - - @property - def zip_code(self): - return "Unknown" - - @property - def citation(self): - return "Not Specified" - - ''' - city = "Unknown" # Column('City', String, nullable=False) - state = "Unknown" # Column('State', String, nullable=False) - zip_code = "Unknown" # Column('ZipCode', String, nullable=False) - citation = "Not specified" - #iso_metadata_id = Column('MetadataID', Integer, ForeignKey('ODM2.ISOMetadata.Metadataid'), nullable=False) - ''' - # relationships - # iso_metadata = relationship(ISOMetadata) - - def __repr__(self): - return "" % \ - (self.id, self.contact_name, self.first_name, self.last_name, - self.phone, self.organization, self.description) - - -class ISOMetadata(Base): - __tablename__ = 'isometadata' - __table_args__ = {u'schema': u'odm2'} - - id = Column('metadataid', Integer, primary_key=True) - topic_category = Column('topiccategory', String, nullable=False) - title = Column('title', String, nullable=False) - abstract = Column('abstract', String, nullable=False) - profile_version = Column('profileversion', String, nullable=False) - metadata_link = Column('metadatalink', String) - - def __repr__(self): - return "" % (self.id, self.topic_category, self.title) - - -# ################################################################################### -# Data Collection Methods -# ################################################################################### - - -class LabMethod(Base): - __tablename__ = 'labmethods' - __table_args__ = {u'schema': u'odm2'} - - id = Column('labmethodid', Integer, primary_key=True) - name = Column('labname', String, nullable=False) - organization = Column('laborganization', String, nullable=False) - method_name = Column('labmethodname', String, nullable=False) - method_description = Column('labmethoddescription', String, nullable=False) - method_link = Column('labmethodlink', String) - - def __repr__(self): - return "" % (self.id, self.name, self.organization, self.method_name) - - -class Method(Base): - # __table__ = method_tabl - __tablename__ = 'methods' - __table_args__ = {u'schema': u'odm2'} - - id = Column('methodid', Integer, primary_key=True) - description = Column('methoddescription', String, nullable=False) - link = Column('methodlink', String) - - def __repr__(self): - return "" % (self.id, self.description, self.link) - - -# ################################################################################### -# ODMVersion -# ################################################################################### -# class ODMVersion: -# #__tablename__ = 'ODMVersion' -# -# # version_number = Column('VersionNumber', String, primary_key=True) -# # version_number = column_property('2.0') -# -# @property -# def version_number(self): -# return "2.0" -# -# def __repr__(self): -# return "" % (self.version_number) - - -class CensorCodeCV(Base): - __tablename__ = 'cv_censorcode' - __table_args__ = {u'schema': 'odm2'} - - term = Column('term', String, primary_key=True) - definition = Column('definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class DataTypeCV(Base): - __tablename__ = 'cv_datasettype' #TODO correct table? - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) # Declare a mapped class - - -# class GeneralCategoryCV(Base): -# __tablename__ = 'cvterms'#TODO correct table? -# -# term = Column('Term', String, primary_key=True) -# definition = Column('Definition', String) -# -# def __repr__(self): -# return "" % (self.term, self.definition) - -class SampleMediumCV(Base): - __tablename__ = 'cv_sampledmedium' - __table_args__ = {u'schema': 'odm2'} - - term = Column('term', String, primary_key=True) - definition = Column('definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class SampleTypeCV(Base): - __tablename__ = 'cv_specimentype' #TODO correct table? - - term = Column('Term', String, primary_key=True) - definition = Column('Definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class SiteTypeCV(Base): - __tablename__ = 'cv_sitetype' - __table_args__ = {u'schema': 'odm2'} - - term = Column('term', String, primary_key=True) - definition = Column('definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class SpeciationCV(Base): - __tablename__ = 'cv_speciation' - __table_args__ = {u'schema': 'odm2'} - - term = Column('term', String, primary_key=True) - definition = Column('definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -# class TopicCategoryCV(Base): -# __tablename__ = 'cvterms'#TODO correct table? -# -# term = Column('Term', String, primary_key=True) -# definition = Column('Definition', String) -# -# def __repr__(self): -# return "" % (self.term, self.definition) -# -# class ValueTypeCV(Base): -# __tablename__ = 'cvterms'#TODO correct table? -# -# term = Column('Term', String, primary_key=True) -# definition = Column('Definition', String) -# -# def __repr__(self): -# return "" % (self.term, self.definition) - -class VariableNameCV(Base): - __tablename__ = 'cv_variablename' - __table_args__ = {u'schema': 'odm2'} - - term = Column('term', String, primary_key=True) - definition = Column('definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class VerticalDatumCV(Base): - __tablename__ = 'cv_elevationdatum' - __table_args__ = {u'schema': 'odm2'} - - term = Column('term', String, primary_key=True) - definition = Column('definition', String) - - def __repr__(self): - return "" % (self.term, self.definition) - - -class Sample(Base): - __tablename__ = 'samples' - __table_args__ = {u'schema': u'odm2'} - - id = Column('sampleid', Integer, primary_key=True) - type = Column('sampletype', String, nullable=False) - lab_sample_code = Column('labsamplecode', String, nullable=False) - lab_method_id = Column('labmethodid', Integer, ForeignKey(LabMethod.id), nullable=False) - - # relationships - lab_method = relationship(LabMethod, primaryjoin=lab_method_id == LabMethod.id) - - def __repr__(self): - return "" % (self.id, self.type, self.lab_sample_code, self.lab_method_id) - - -class Qualifier(Base): - __tablename__ = u'annotations' - __table_args__ = {u'schema': u'odm2'} - - id = Column('annotationid', Integer, primary_key=True) - code = Column('annotationcode', String, nullable=False) - description = Column('annotationtext', String, nullable=False) - - def __repr__(self): - return "" % (self.id, self.code, self.description) - - -#TODO Table no longer exists -class OffsetType(Base): - __tablename__ = u'timeseriesresults' - __table_args__ = {u'schema': 'ODM2'} - - id = Column('offsettypeid', Integer, primary_key=True) - unit_id = Column('zlocationunitsid', Integer, ForeignKey(Unit.id), nullable=False) - description = Column('offsetdescription', String) - - # relationships - unit = relationship(Unit, primaryjoin=unit_id == Unit.id) - - def __repr__(self): - return "" % (self.id, self.unit_id, self.description) - - -class QualityControlLevel(Base): - __tablename__ = u'processinglevels' - __table_args__ = {u'schema': u'ODM2'} - - id = Column('processinglevelid', Integer, primary_key=True) - code = Column('processinglevelcode', String, nullable=False) - definition = Column('definition', String, nullable=False) - explanation = Column('explanation', String, nullable=False) - - def __repr__(self): - return "" % (self.id, self.code, self.definition, self.explanation) - - -timeseriesresultvalues_table = TimeSeriesResultValues.__table__ -# timeseriesresults_table = TimeSeriesResults.__table__ - -feature_action_table = FeatureActions.__table__ -feature_action_table = select([ - feature_action_table.c.actionid.label("actid"), - feature_action_table.c.featureactionid.label("FeAID"), - feature_action_table.c.samplingfeatureid.label("SFID") -]).alias("odm2_featureactions") - -action_table = Actions.__table__ -action_aliased_table = select([ - action_table.c.actionid.label("AID"), - action_table.c.methodid, - action_table.c.begindatetime, - action_table.c.enddatetime -]).alias("odm2_actions") - -action_by_table = ActionBy.__table__ -action_by_aliased_table = select([ - action_by_table.c.actionid.label("ABID"), - action_by_table.c.affiliationid, -]).alias("odm2_actionby") - -joined_table = result_aliased_table.join(feature_action_table, - result_aliased_table.c.FAID == feature_action_table.c.FeAID) -joined_table = joined_table.join(action_aliased_table, - joined_table.c.odm2_featureactions_actid == action_aliased_table.c.AID) -joined_table = joined_table.join(action_by_aliased_table, - joined_table.c.odm2_actions_AID == action_by_aliased_table.c.ABID) -joined_table = joined_table.join(timeseriesresultvalues_table, - joined_table.c.odm2_results_RID == timeseriesresultvalues_table.c.resultid) - -''' -joined_table = timeseriesresultvalues_table.join(result_aliased_table, timeseriesresultvalues_table.c.resultid == - result_aliased_table.c.RID) -#joined_table = joined_table.join(feature_action_table, joined_table.c.odm2_results_FAID==feature_action_table.c.FeAID) -#joined_table = joined_table.join(action_aliased_table, joined_table.c.odm2_featureactions_actid == action_aliased_table.c.AID) -#joined_table = joined_table.join(action_by_aliased_table, joined_table.c.odm2_actions_AID == action_by_aliased_table.c.ABID) -''' - - -from datetime import timedelta -class DataValue(Base): - # __tablename__ = 'DataValues' - __table__ = joined_table - - id = joined_table.c.odm2_timeseriesresultvalues_valueid - data_value = joined_table.c.odm2_timeseriesresultvalues_datavalue - value_accuracy = None #column_property(0) ## question for jeff - local_date_time = joined_table.c.odm2_timeseriesresultvalues_valuedatetime - utc_offset = joined_table.c.odm2_timeseriesresultvalues_valuedatetimeutcoffset - site_id = joined_table.c.odm2_featureactions_SFID #joined_table.c.odm2_featureactions_FeAID - variable_id = joined_table.c.odm2_results_variableid - offset_value = None # column_property(-1) ## Question for jeff - offset_type_id = None # column_property(-1)#None ## Question for Jeff - censor_code = joined_table.c.odm2_timeseriesresultvalues_censorcodecv - - method_id = joined_table.c.odm2_actions_methodid - source_id = joined_table.c.odm2_actionby_affiliationid - sample_id = column_property(site_id) # Question for jeff - derived_from_id = None # column_property(-1) - quality_control_level_id = joined_table.c.odm2_timeseriesresultvalues_qualitycodecv - - qualifier_id = None # Join with annotations.. - # date_time_utc = column_property(local_date_time+utc_offset) ## column property datetimeutcoffset - # @declared_attr - - @property - def date_time_utc(cls): - return cls.local_date_time - timedelta(hours=cls.utc_offset) - - # relationships - # site = relationship(Site, primaryjoin = site_id==Site.id) - variable = relationship(Variable, primaryjoin=variable_id == Variable.id) - # method = relationship(Method,primaryjoin =method_id == Method.id) - source = relationship(Source, primaryjoin=source_id == Source.id) - # quality_control_level = relationship(QualityControlLevel, primaryjoin =quality_control_level_id==QualityControlLevel.id) - - # qualifier = relationship(Qualifier, primaryjoin =qualifier_id==Qualifier.id) - # offset_type = relationship(OffsetType, primaryjoin =offset_type_id==OffsetType.id) - # sample = relationship(Sample, primaryjoin =sample_id == Sample.id) - - def list_repr(self): - return [self.id, self.data_value, self.value_accuracy, self.local_date_time, - self.utc_offset, self.date_time_utc, self.site_id, self.variable_id, - self.offset_value, self.offset_type_id, self.censor_code, self.qualifier_id, - self.method_id, self.source_id, self.sample_id, self.derived_from_id, - self.quality_control_level_id] - - # def __repr__(self): - # return "" % (self.id, self.data_value, self.local_date_time, self.value_accuracy) - # - def __repr__(self): - return "" % ', '.join([str(x) for x in self.list_repr()]) - - -''' -/anaconda/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py:353: SAWarning: On class 'DataValue', Column object 'samplingfeatureid' named directly multiple times, only one will be used: sample_id, site_id - (self.classname, name, (", ".join(sorted(keys)))) -''' - -method_table = Methods().__table__ -method_table = select([ - method_table.c.methodid, - method_table.c.methoddescription, - # method_table.c.organizationid.label('methodorgid'), - -]).alias("odm2_methods") - -processing_levels_table = ProcessingLevels().__table__ -''' -joined_table_2 = feature_action_table.join(result_aliased_table, feature_action_table.c.FeAID == - result_aliased_table.c.FAID) -# Obtain TSResults -joined_table_2 = joined_table_2.join(ts_table, joined_table_2.c.odm2_results_RID == - ts_table.c.resultid) -''' -joined_table_2 = result_aliased_table.join(ts_table, result_aliased_table.c.RID== ts_table.c.resultid) -joined_table_2= joined_table_2.join(feature_action_table, joined_table_2.c.odm2_results_FAID== feature_action_table.c.FeAID) - -joined_table_2 = joined_table_2.join(site_join, joined_table_2.c.odm2_featureactions_SFID == - site_join.c.odm2_sites_samplingfeatureid) -joined_table_2 = joined_table_2.join(variables_table, joined_table_2.c.odm2_results_variableid == - variables_table.c.variableid) - - -# Obtaining Action -joined_table_2 = joined_table_2.join(action_aliased_table, joined_table_2.c.odm2_featureactions_actid == - action_aliased_table.c.AID) - -# Obtaining Method -joined_table_2 = joined_table_2.join(method_table, joined_table_2.c.odm2_actions_methodid == - method_table.c.methodid) - -# Obtaining Source -joined_table_2 = joined_table_2.join(action_by_table, joined_table_2.c.odm2_actions_AID == - action_by_table.c.actionid) -joined_table_2 = joined_table_2.join(source_join, joined_table_2.c.odm2_actionby_affiliationid == - source_join.c.odm2_affiliations_affiliationid) - -# Obtaining Processing Level -joined_table_2 = joined_table_2.join(processing_levels_table, joined_table_2.c.odm2_results_processinglevelid == - processing_levels_table.c.processinglevelid) - -''' -class Series: - print "test" - pass -''' - - -class Series(Base): - # __tablename__ = 'SeriesCatalog' - __table__ = joined_table_2 - - id = joined_table_2.c.odm2_results_RID - - site_id = joined_table_2.c.odm2_sites_samplingfeatureid - - site_code = joined_table_2.c.odm2_samplingfeatures_samplingfeaturecode - site_name = joined_table_2.c.odm2_samplingfeatures_samplingfeaturename - variable_id = joined_table_2.c.odm2_results_variableid - variable_code = joined_table_2.c.odm2_variables_variablecode - variable_name = joined_table_2.c.odm2_variables_variablenamecv - speciation = joined_table_2.c.odm2_variables_speciationcv - variable_units_id = joined_table_2.c.odm2_results_unitsid - variable_units_name = None # joined_table.c. - sample_medium = joined_table_2.c.odm2_results_sampledmediumcv - value_type = joined_table_2.c.odm2_variables_variabletypecv - time_support = joined_table_2.c.odm2_timeseriesresults_intendedtimespacing # Column('TimeSupport', Float, nullable=False) - time_unit_id = joined_table_2.c.odm2_timeseriesresults_intendedtimespacingunitsid # Column('TimeUnitsID', Integer, ForeignKey('Units.UnitsID'), nullable=False) - data_type = joined_table_2.c.odm2_timeseriesresults_aggregationstatisticcv - time_units_name = None # join with units - general_category = None - method_id = joined_table_2.c.odm2_methods_methodid - method_description = joined_table_2.c.odm2_methods_methoddescription - source_id = joined_table_2.c.odm2_affiliations_affiliationid - description = joined_table_2.c.odm2_organizations_organizationdescription # Column('OrganizationDescription', String, nullable=False) - link = joined_table_2.c.odm2_organizations_organizationlink - citation = None # please calculate - quality_control_level_id = joined_table_2.c.odm2_processinglevels_processinglevelid - quality_control_level_code = joined_table_2.c.odm2_processinglevels_processinglevelcode - begin_date_time = joined_table_2.c.odm2_actions_begindatetime - end_date_time = joined_table_2.c.odm2_actions_enddatetime - - value_count = joined_table_2.c.odm2_results_valuecount - - # begin_date_time_utc = None # Column('BeginDateTimeUTC', DateTime) - # end_date_time_utc = None # Column('EndDateTimeUTC', DateTime) - utc_offset = -7 # joined_table_2.c.odm2_timeseriesresultvalues_valuedatetimeutcoffset - - @property - def begin_date_time_utc(cls): - val = cls.begin_date_time - timedelta(hours=cls.utc_offset) - return val - - @property - def end_date_time_utc(cls): - return cls.end_date_time - timedelta(hours=cls.utc_offset) - - # data_values = relationship("DataValue", - # primaryjoin="and_(DataValue.site_id == Series.site_id, " - # "DataValue.variable_id == Series.variable_id, " - # "DataValue.method_id == Series.method_id, " - # "DataValue.source_id == Series.source_id, " - # "DataValue.quality_control_level_id == Series.quality_control_level_id)", - # foreign_keys="[DataValue.site_id, DataValue.variable_id, DataValue.method_id, DataValue.source_id, DataValue.quality_control_level_id]", - # order_by="DataValue.local_date_time", - # backref="series") - # - # site = relationship(Site, primaryjoin = site_id==Site.id) - variable = relationship(Variable, primaryjoin=variable_id == Variable.id) - # method = relationship(Method, primaryjoin= method_id ==Method.id) - # source = relationship(Source, primaryjoin= source_id ==Source.id) - # quality_control_level = relationship(QualityControlLevel, primaryjoin = quality_control_level_id==QualityControlLevel.id) - - # TODO add all to repr - def __repr__(self): - return "" % (self.id) - - def get_table_columns(self): - return self.__table__.columns.keys() - - -import inspect -import sys - - -def change_schema(schema): - # 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: - Tbl.__table__.schema = schema - - -from collections import OrderedDict # Requires Python 2.7 >= - - -def returnDict(): - keys = ['SeriesID', 'SiteID', 'SiteCode', 'SiteName', 'VariableID', 'VariableCode', 'VariableName', 'Speciation', - 'VariableUnitsID', 'VariableUnitsName', 'SampleMedium', 'ValueType', 'TimeSupport', 'TimeUnitsID', - 'TimeUnitsName', 'DataType', 'GeneralCategory', 'MethodID', 'MethodDescription', 'SourceID', - 'SourceDescription', 'Organization', 'Citation', 'QualityControlLevelID', 'QualityControlLevelCode', - 'BeginDateTime', 'EndDateTime', 'BeginDateTimeUTC', 'EndDateTimeUTC', 'ValueCount' - ] - values = ['id', 'site_id', 'site_code', 'site_name', 'variable_id', 'variable_code', 'variable_name', 'speciation', - 'variable_units_id', 'variable_units_name', 'sample_medium', 'value_type', 'time_support', - 'time_units_id', 'time_units_name', 'data_type', 'general_category', 'method_id', 'method_description', - 'source_id', 'source_description', 'organization', 'citation', 'quality_control_level_id', - 'quality_control_level_code', 'begin_date_time', 'end_date_time', 'begin_date_time_utc', - 'end_date_time_utc', 'value_count' - ] - return OrderedDict(zip(keys, values)) \ No newline at end of file diff --git a/odm2api/ODM2/__init__.py b/odm2api/ODM2/__init__.py index aff2b45..96c3005 100644 --- a/odm2api/ODM2/__init__.py +++ b/odm2api/ODM2/__init__.py @@ -1,7 +1,8 @@ -from odm2api.base import serviceBase -from odm2api.base import modelBase +from __future__ import (absolute_import, division, print_function) + +from odm2api.base import modelBase, serviceBase __all__ = [ 'serviceBase', 'modelBase', - ] +] diff --git a/odm2api/ODM2/apiCustomType.py b/odm2api/ODM2/apiCustomType.py deleted file mode 100644 index 903d284..0000000 --- a/odm2api/ODM2/apiCustomType.py +++ /dev/null @@ -1,132 +0,0 @@ -from sqlalchemy import func -from sqlalchemy.sql.expression import FunctionElement, ClauseElement, Executable -#from sqlalchemy.types import UserDefinedType -from sqlalchemy.ext.compiler import compiles - - -from geoalchemy2 import Geometry as GeometryBase - -# function to pull from the database -def compiles_as_bound(cls): - - @compiles(cls) - def compile_function(element, compiler, **kw): - return None - - @compiles(cls, 'postgresql') - def compile_function(element, compiler, **kw): - val = "%s(%s)"%(element.name, compiler.process(element.clauses.clauses[0])) - #ST_AsText("\"ODM2\".\"SamplingFeatures\".\"FeatureGeometry\"") - return val - - @compiles(cls, 'mysql') - def compile_function(element, compiler, **kw): - val="%s(%s)"%(element.name.lower().split('_')[1], compiler.process(element.clauses.clauses[0])) - #astext("`ODM2`.`SamplingFeatures`.`FeatureGeometry`") - #ST_astext() - return val - - @compiles(cls, 'sqlite') - def compile_function(element, compiler, **kw): - #ST_AsText(samplingfeatures.featuregeometry) - #assuming the user is using spatialite - #return "%s(%s)"%(element.name.split('_')[-1], compiler.process(element.clauses.clauses[0])) - #what if user does not have a spatial db? - return "%s"%compiler.process(element.clauses.clauses[0]) - - @compiles(cls, 'mssql') - def compile_function(element, compiler, **kw): - #[SamplingFeatures].[FeatureGeometry].STAsText() - return "%s.%s()" % (compiler.process(element.clauses.clauses[0]), element.name.replace('_', '') ) - - return cls - - - -# function to save to the database -def saves_as_bound(cls): - - @compiles(cls) - def compile_function(element, compiler, **kw): - return element - - @compiles(cls, 'postgresql') - def compile_function(element, compiler, **kw): - #print "postgresql Save : %s" % element.__str__() - return "%s(%s)"%(element.name, "'POINT(30 10)'") - - @compiles(cls, 'mysql') - def compile_function(element, compiler, **kw): - name= element.name.split('_')[-1] - - # GeomFromText("POINT(30 10)") - # GeomFromText(:featuregeometry) - - val = "%s(%s)"%(name, compiler.process(element.bindelement)) - return val - - @compiles(cls, 'sqlite') - def compile_function(element, compiler, **kw): - name= element.name.split('_')[-1] - #return "%s(%s)" % (element.name.replace('_', ''), "'POINT (30 10)'") - #assuming the user is using spatialite - #return "%s(%s)"%(name, "'POINT(30 10)'") - - #what if user does not have a spatial? -# >>> self.bindtemplate -# '?' -# (BindParameter('featuregeometry', None, type_=Geometry()),) -# >>> dialect.paramstyle - #print compiler.bindtemplate - return "%s(%s)"%(name, '') - - @compiles(cls, 'mssql') - def compile_function(element, compiler, **kw): - #return "Geometry::%s(%s, 0)"%(element.name.replace('_', ''), "'POINT (30 10)'") - name = "Geometry::%s" % element.name.replace('_', '') - - return "%s(%s,0)"%(name, "'POINT(30 10)'") - - return cls - - - -@saves_as_bound -class ST_GeomFromText(FunctionElement): - name = "ST_GeomFromText" - - - -@compiles_as_bound -class ST_AsText(FunctionElement): - name = 'ST_AsText' - -@compiles_as_bound -class ST_AsBinary(FunctionElement): - name = 'ST_AsBinary' - - - -class Geometry(GeometryBase): - - def column_expression(self, col): - value = ST_AsText(col, type_=self) - if value is None: - value = func.ST_AsText(col, type_=self) - return value - - def bind_expression(self, bindvalue): - val = None - # mysql, sqlite - val = func.GeomFromText(bindvalue, type_=self) - - # postgresql - # val = func.ST_GeomFromText(bindvalue, type_=self) - # mssql - if val is None: - val = ST_GeomFromText(bindvalue, type_=self) - return val - - - - diff --git a/odm2api/ODM2/models.py b/odm2api/ODM2/models.py index b05f351..7b6d5b2 100644 --- a/odm2api/ODM2/models.py +++ b/odm2api/ODM2/models.py @@ -1,15 +1,10 @@ -from sqlalchemy import BigInteger, Column, Date, DateTime, Float, ForeignKey, Integer, String, Boolean, BLOB -from sqlalchemy.orm import relationship -from sqlalchemy.dialects import postgresql, mysql, sqlite -# Should not be importing anything from a specific dialect -# from sqlalchemy.dialects.mssql.base import BIT - -from geoalchemy import GeometryDDL, GeometryColumn -from geoalchemy.geometry import Geometry -from shapely import wkb, wkt +from __future__ import (absolute_import, division, print_function) from odm2api.base import modelBase -# from apiCustomType import Geometry + +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 @@ -30,11 +25,8 @@ def is_hex(s): ################################################################################ # CV ################################################################################ - - -class CVActionType(Base): - __tablename__ = 'cv_actiontype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class CV (object): + __table_args__ = {u'schema': 'odm2'} Term = Column('term', String(255), nullable=False) Name = Column('name', String(255), primary_key=True) @@ -42,419 +34,140 @@ class CVActionType(Base): Category = Column('category', String(255)) SourceVocabularyURI = Column('sourcevocabularyuri', String(255)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVAggregationStatistic(Base): - __tablename__ = 'cv_aggregationstatistic' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class CVActionType(Base, CV): + __tablename__ = 'cv_actiontype' - 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)) - def __repr__(self): - return "" % ( - self.Term, self.Name, self.Definition, self.Category) +class CVAggregationStatistic(Base, CV): + __tablename__ = 'cv_aggregationstatistic' -class CVAnnotationType(Base): +class CVAnnotationType(Base, CV): __tablename__ = 'cv_annotationtype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVCensorCode(Base): +class CVCensorCode(Base, CV): __tablename__ = 'cv_censorcode' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVDataQualityType(Base): +class CVDataQualityType(Base, CV): __tablename__ = 'cv_dataqualitytype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVDataSetType(Base): +class CVDataSetType(Base, CV): __tablename__ = 'cv_datasettypecv' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVDeploymentType(Base): +class CVDeploymentType(Base, CV): __tablename__ = 'cv_deploymenttype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVDirectiveType(Base): +class CVDirectiveType(Base, CV): __tablename__ = 'cv_directivetype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVElevationDatum(Base): +class CVElevationDatum(Base, CV): __tablename__ = 'cv_elevationdatum' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVEquipmentType(Base): +class CVEquipmentType(Base, CV): __tablename__ = 'cv_equipmenttype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVMediumType(Base): +class CVMediumType(Base, CV): __tablename__ = 'cv_medium' - __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)) - def __repr__(self): - return "" %(self.Term, self.Name, self.Definition, self.Category) -class CVMethodType(Base): +class CVMethodType(Base, CV): __tablename__ = 'cv_methodtype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVOrganizationType(Base): +class CVOrganizationType(Base, CV): __tablename__ = 'cv_organizationtype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVPropertyDataType(Base): +class CVPropertyDataType(Base, CV): __tablename__ = 'cv_propertydatatype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVQualityCode(Base): +class CVQualityCode(Base, CV): __tablename__ = 'cv_qualitycode' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVResultType(Base): +class CVResultType(Base, CV): __tablename__ = 'cv_resulttype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVRelationshipType(Base): +class CVRelationshipType(Base, CV): __tablename__ = 'cv_relationshiptype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVSamplingFeatureGeoType(Base): +class CVSamplingFeatureGeoType(Base, CV): __tablename__ = 'cv_samplingfeaturegeotype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVSamplingFeatureType(Base): +class CVSamplingFeatureType(Base, CV): __tablename__ = 'cv_samplingfeaturetype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVSpatialOffsetType(Base): +class CVSpatialOffsetType(Base, CV): __tablename__ = 'cv_spatialoffsettype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVSpeciation(Base): +class CVSpeciation(Base, CV): __tablename__ = 'cv_speciation' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVSpecimenType(Base): +class CVSpecimenType(Base, CV): __tablename__ = 'cv_specimentype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVSiteType(Base): +class CVSiteType(Base, CV): __tablename__ = 'cv_sitetype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVStatus(Base): +class CVStatus(Base, CV): __tablename__ = 'cv_status' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVTaxonomicClassifierType(Base): +class CVTaxonomicClassifierType(Base, CV): __tablename__ = 'cv_taxonomicclassifiertype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVUnitsType(Base): +class CVUnitsType(Base, CV): __tablename__ = 'cv_unitstype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVVariableName(Base): +class CVVariableName(Base, CV): __tablename__ = 'cv_variablename' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) -class CVVariableType(Base): +class CVVariableType(Base, CV): __tablename__ = 'cv_variabletype' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - 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)) - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVReferenceMaterialMedium(Base): +class CVReferenceMaterialMedium(Base, CV): __tablename__ = 'cv_referencematerialmedium' - __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) # ################################################################################ # Core # ################################################################################ class People(Base): - __tablename__ = u'people' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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) - def __repr__(self): - return "" % (self.PersonID, self.PersonFirstName, - self.PersonLastName) - class Organizations(Base): - __tablename__ = u'organizations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + A group of people. + """ OrganizationID = Column('organizationid', Integer, primary_key=True, nullable=False) OrganizationTypeCV = Column('organizationtypecv', ForeignKey(CVOrganizationType.Name), nullable=False, index=True) @@ -466,16 +179,8 @@ class Organizations(Base): OrganizationObj = relationship(u'Organizations', remote_side=[OrganizationID]) - def __repr__(self): - return "" % ( - self.OrganizationID, self.OrganizationTypeCV, self.OrganizationCode, - self.OrganizationName, self.OrganizationDescription, self.OrganizationLink - ) - class Affiliations(Base): - __tablename__ = 'affiliations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} AffiliationID = Column('affiliationid', Integer, primary_key=True, nullable=False) PersonID = Column('personid', ForeignKey(People.PersonID), nullable=False) @@ -493,9 +198,9 @@ class Affiliations(Base): class Methods(Base): - __tablename__ = 'methods' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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) @@ -506,16 +211,11 @@ class Methods(Base): OrganizationObj = relationship(Organizations) - def __repr__(self): - return "" \ - % (self.MethodID, self.MethodTypeCV, self.MethodCode, self.MethodName, self.MethodDescription, - self.MethodLink, self.OrganizationID) - class Actions(Base): - __tablename__ = u'actions' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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) @@ -528,14 +228,8 @@ class Actions(Base): MethodObj = relationship(Methods) - def __repr__(self): - return "" % ( - self.ActionID, self.ActionTypeCV, self.BeginDateTime, self.ActionDescription) - class ActionBy(Base): - __tablename__ = u'actionby' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) ActionID = Column('actionid', Integer, ForeignKey(Actions.ActionID), nullable=False) @@ -548,59 +242,58 @@ class ActionBy(Base): class SamplingFeatures(Base): - __tablename__ = u'samplingfeatures' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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""" ElevationDatumCV = Column('elevationdatumcv', ForeignKey(CVElevationDatum.Name), index=True) - FeatureGeometry = Column('featuregeometry', Geometry) - # FeatureGeometry = Column('featuregeometry', BLOB) # custom geometry queries - - def shape(self): - """ - Method name based on shapely shapely.geometry.shape() function. - Returns a shapely geometry object - :return geomshape: - """ - _FeatureGeometry = self.FeatureGeometry - geomshape = None - if _FeatureGeometry is not None: - if is_hex(_FeatureGeometry.geom_wkb): - # to parse wkb hex string directly - geomshape = wkb.loads(_FeatureGeometry.geom_wkb, hex=True) - # _FeatureGeometry = GeometryColumn('featuregeometry', Geometry) - else: - geomshape = wkt.loads(str(_FeatureGeometry.geom_wkb)) - - return geomshape - - def __repr__(self): - geom = self.shape() - if geom is not None: - geomkt = geom.wkt - else: - geomkt = None - - return "" % ( - self.SamplingFeatureCode, self.SamplingFeatureName, self.SamplingFeatureDescription, - self.Elevation_m, geomkt) - -GeometryDDL(SamplingFeatures.__table__) # Geoalchemy1 + """str: The code for the vertical geodetic datum that specifies the zero point for + the Sampling Feature Elevation""" + # 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). """ + + 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).""" + __mapper_args__ = { + 'polymorphic_on': case( + [ + (SamplingFeatureTypeCV == 'Specimen', 'Specimen'), + (SamplingFeatureTypeCV == 'Site', 'Site'), + ], + else_='samplingfeatures'), + 'polymorphic_identity': 'samplingfeatures', + } class FeatureActions(Base): - __tablename__ = u'featureactions' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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) @@ -609,14 +302,11 @@ class FeatureActions(Base): ActionObj = relationship(Actions) SamplingFeatureObj = relationship(SamplingFeatures) - def __repr__(self): - return "" % (self.FeatureActionID, self.SamplingFeatureID, self.ActionID) - class DataSets(Base): - __tablename__ = u'datasets' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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 @@ -626,29 +316,21 @@ class DataSets(Base): DataSetTitle = Column('datasettitle', String(255), nullable=False) DataSetAbstract = Column('datasetabstract', String(500), nullable=False) - def __repr__(self): - return "" % ( - self.DataSetID, self.DataSetTypeCV, self.DataSetCode, self.DataSetTitle, self.DataSetAbstract) - class ProcessingLevels(Base): - __tablename__ = u'processinglevels' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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)) - def __repr__(self): - return "" \ - % (self.ProcessingLevelID, self.ProcessingLevelCode, self.Definition, self.Explanation) - class RelatedActions(Base): - __tablename__ = u'relatedactions' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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, @@ -660,40 +342,41 @@ class RelatedActions(Base): class TaxonomicClassifiers(Base): - __tablename__ = u'taxonomicclassifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + Terms for classifying results. + """ TaxonomicClassifierID = Column('taxonomicclassifierid', Integer, primary_key=True, nullable=False) - TaxonomicClassifierTypeCV = Column('taxonomicclassifiertypecv', ForeignKey(CVTaxonomicClassifierType.Name), - nullable=False, index=True) + 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')) + 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): - __tablename__ = u'units' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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)) - def __repr__(self): - return "" % ( - self.UnitsID, self.UnitsTypeCV, self.UnitsAbbreviation, self.UnitsName) - class Variables(Base): - __tablename__ = u'variables' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + 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) @@ -702,31 +385,11 @@ class Variables(Base): SpeciationCV = Column('speciationcv', ForeignKey(CVSpeciation.Name), index=True) NoDataValue = Column('nodatavalue', Float(asdecimal=True), nullable=False) - def __repr__(self): - return "" % (self.VariableID, self.VariableCode, self.VariableNameCV) - - -''' -class ResultTypeCV(Base): - __tablename__ = u'ResultTypeCV' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - ResultTypeCV = Column(String(255), primary_key=True) - ResultTypeCategory = Column(String(255), nullable=False) - DataType = Column(String(255), nullable=False) - ResultTypeDefinition = Column(String(500), nullable=False) - FixedDimensions = Column(String(255), nullable=False) - VaryingDimensions = Column(String(255), nullable=False) - SpaceMeasurementFramework = Column(String(255), nullable=False) - TimeMeasurementFramework = Column(String(255), nullable=False) - VariableMeasurementFramework = Column(String(255), nullable=False) -''' - class Results(Base): - __tablename__ = u'results' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - + """ + The result of an action. + """ ResultID = Column('resultid', BigIntegerType, primary_key=True) # This has been changed to String to support multiple database uuid types @@ -748,8 +411,6 @@ class Results(Base): SampledMediumCV = Column('sampledmediumcv', ForeignKey(CVMediumType.Name), nullable=False, index=True) ValueCount = Column('valuecount', Integer, nullable=False) - # IntendedObservationSpacing = Column(String(255)) - FeatureActionObj = relationship(FeatureActions) ProcessingLevelObj = relationship(ProcessingLevels) @@ -757,20 +418,56 @@ class Results(Base): UnitsObj = relationship(Units) VariableObj = relationship(Variables) - def __repr__(self): - return "" % ( - self.ResultID, self.ResultUUID, self.ResultTypeCV, self.ProcessingLevelID, self.ValueCount) + __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('actionid', Integer, ForeignKey(DataLoggerProgramFiles.ProgramID), nullable=False) + DataLoggerFileName = Column('dataloggerfilename', String(255), nullable=False) + DataLoggerOutputFileDescription = Column('dataloggeroutputfiledescription', String(500)) + DataLoggerOutputFileLink = Column('dataloggeroutputfilelink', String(255)) + + ProgramObj = relationship(DataLoggerProgramFiles) + + class EquipmentModels(Base): - __tablename__ = u'equipmentmodels' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ModelID = Column('modelid', Integer, primary_key=True, nullable=False) - ModelManufacturerID = Column('modelmanufacturerid', ForeignKey(Organizations.OrganizationID), 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)) @@ -781,9 +478,65 @@ class EquipmentModels(Base): 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', BigInteger, 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('measurmentequation', 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): - __tablename__ = u'equipment' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} EquipmentID = Column('equipmentid', Integer, primary_key=True, nullable=False) EquipmentCode = Column('equipmentcode', String(50), nullable=False) @@ -796,52 +549,96 @@ class Equipment(Base): EquipmentVendorID = Column('equipmentvendorid', ForeignKey(Organizations.OrganizationID), nullable=False) EquipmentPurchaseDate = Column('equipmentpurchasedate', DateTime, nullable=False) EquipmentPurchaseOrderNumber = Column('equipmentpurchaseordernumber', String(50)) - EquipmentPhotoFileLink = Column('equipmentphotofilelink', String(255)) EquipmentDescription = Column('equipmentdescription', String(500)) - ParentEquipmentID = Column('parentequipmentid', ForeignKey('odm2.equipment.equipmentid')) PersonObj = relationship(People) OrganizationObj = relationship(Organizations) EquipmentModelObj = relationship(EquipmentModels) - parent = relationship(u'Equipment', remote_side=[EquipmentID]) + +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): - __tablename__ = u'equipmentactions' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} 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 InstrumentOutputVariables(Base): - __tablename__ = u'instrumentoutputvariables' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class EquipmentUsed(Base): - InstrumentOutputVariableID = Column('instrumentoutputvariableid', Integer, primary_key=True, nullable=False) - ModelID = Column('modelid', ForeignKey(EquipmentModels.ModelID), nullable=False) - VariableID = Column('variableid', ForeignKey(Variables.VariableID), nullable=False) - InstrumentMethodID = Column('instrumentmethodid', ForeignKey(Methods.MethodID), nullable=False) - InstrumentResolution = Column('instrumentresolution', String(255)) - InstrumentAccuracy = Column('instrumentaccuracy', String(255)) - InstrumentRawOutputUnitsID = Column('instrumentrawoutputunitsid', ForeignKey(Units.UnitsID), nullable=False) + 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) - MethodObj = relationship(Methods) - OutputUnitObj = relationship(Units) - EquipmentModelObj = relationship(EquipmentModels) - VariableObj = relationship(Variables) + 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): - __tablename__ = u'directives' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} DirectiveID = Column('directiveid', Integer, primary_key=True, nullable=False) DirectiveTypeCV = Column('directivetypecv', ForeignKey(CVDirectiveType.Name), nullable=False, index=True) @@ -849,8 +646,6 @@ class Directives(Base): class ActionDirectives(Base): - __tablename__ = u'actiondirectives' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) @@ -860,12 +655,27 @@ class ActionDirectives(Base): 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): - __tablename__ = u'spatialreferences' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} SpatialReferenceID = Column('spatialreferenceid', Integer, primary_key=True, nullable=False) SRSCode = Column('srscode', String(50)) @@ -873,14 +683,8 @@ class SpatialReferences(Base): SRSDescription = Column('srsdescription', String(500)) SRSLink = Column('srslink', String(255)) - def __repr__(self): - return "" \ - % (self.SpatialReferenceID, self.SRSCode, self.SRSName, self.SRSDescription, self.SRSLink) - -class Specimens(Base): - __tablename__ = u'specimens' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class Specimens(SamplingFeatures): SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), primary_key=True) @@ -888,17 +692,17 @@ class Specimens(Base): SpecimenMediumCV = Column('specimenmediumcv', ForeignKey(CVMediumType.Name), nullable=False, index=True) IsFieldSpecimen = Column('isfieldspecimen', Boolean, nullable=False) - SamplingFeatureObj = relationship(SamplingFeatures) + __mapper_args__ = { + 'polymorphic_identity': 'Specimen', + } class SpatialOffsets(Base): - __tablename__ = u'spatialoffsets' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} 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) + 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)) @@ -910,9 +714,7 @@ class SpatialOffsets(Base): Offset3UnitObj = relationship(Units, primaryjoin='SpatialOffsets.Offset3UnitID == Units.UnitsID') -class Sites(Base): - __tablename__ = u'sites' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class Sites(SamplingFeatures): SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), primary_key=True) @@ -923,36 +725,38 @@ class Sites(Base): Longitude = Column('longitude', Float(53), nullable=False) SpatialReferenceObj = relationship(SpatialReferences) - SamplingFeatureObj = relationship(SamplingFeatures) - def __repr__(self): - return "" \ - % (self.SamplingFeatureID, self.SpatialReferenceID, self.SiteTypeCV, self.Latitude, self.Longitude, - self.SpatialReferenceObj, self.SamplingFeatureObj) + __mapper_args__ = { + 'polymorphic_identity': 'Site', + } class RelatedFeatures(Base): - __tablename__ = u'relatedfeatures' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} 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) + 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') + SamplingFeatureObj = relationship( + SamplingFeatures, + primaryjoin='RelatedFeatures.SamplingFeatureID == SamplingFeatures.SamplingFeatureID' + ) + RelatedFeatureObj = relationship( + SamplingFeatures, + primaryjoin='RelatedFeatures.RelatedFeatureID == SamplingFeatures.SamplingFeatureID' + ) SpatialOffsetObj = relationship(SpatialOffsets) class SpecimenTaxonomicClassifiers(Base): - __tablename__ = u'specimentaxonomicclassifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) SamplingFeatureID = Column('samplingfeatureid', ForeignKey(Specimens.SamplingFeatureID), nullable=False) @@ -964,55 +768,10 @@ class SpecimenTaxonomicClassifiers(Base): TaxonomicClassifierObj = relationship(TaxonomicClassifiers) -# ################################################################################ -# Sensors -# ################################################################################ -class DeploymentActions(Base): - __tablename__ = u'deploymentactions' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - DeploymentActionID = Column('deploymentactionid', Integer, primary_key=True, nullable=False) - ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) - DeploymentTypeCV = Column('deploymenttypecv', ForeignKey(CVDeploymentType.Name), nullable=False, index=True) - DeploymentDescription = Column('deploymentdescription', String(500)) - ConfigurationActionID = Column('configurationactionid', Integer, nullable=False) - CalibrationActionID = Column('calibrationactionid', Integer, nullable=False) - SpatialOffsetID = Column('spatialoffsetid', Integer) - DeploymentSchematicLink = Column('deploymentschematiclink', String(255)) - - ActionObj = relationship(Actions) - - -class DataLoggerFiles(Base): - __tablename__ = u'dataloggerfiles' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - DataLoggerFileID = Column('dataloggerfileid', Integer, primary_key=True, nullable=False) - DeploymentActionID = Column('actionid', ForeignKey(DeploymentActions.DeploymentActionID), nullable=False) - DataLoggerOutputFileLink = Column('dataloggeroutputfilelink', String(255), nullable=False) - DataLoggerOutputFileDescription = Column('dataloggeroutputfiledescription', String(500)) - - DeploymentActionObj = relationship(DeploymentActions) - - -class Photos(Base): - __tablename__ = u'photos' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - PhotoID = Column('photoid', Integer, primary_key=True, nullable=False) - ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) - PhotoFileLink = Column('photofilelink', String(255), nullable=False) - PhotoDescription = Column('photodescription', String(500)) - - ActionObj = relationship(Actions) - - # ################################################################################ # Simulation # ################################################################################ class Models(Base): - __tablename__ = 'models' - __table_args__ = {u'schema': 'odm2'} #__table_args__ ={u'schema': Schema.getSchema()} ModelID = Column('modelid', Integer, primary_key=True, nullable=False) ModelCode = Column('modelcode', String(255), nullable=False) @@ -1021,10 +780,8 @@ class Models(Base): class RelatedModels(Base): - __tablename__ = 'relatedmodels' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - RelationID = Column('relationid', Integer, primary_key=True, nullable=False) + 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) @@ -1035,8 +792,6 @@ class RelatedModels(Base): class Simulations(Base): - __tablename__ = 'simulations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} SimulationID = Column('simulationid', Integer, primary_key=True, nullable=False) ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) @@ -1049,7 +804,7 @@ class Simulations(Base): 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 ? + # OutputDataSetID = Column('outputdatasetid', Integer) # What's this ? ModelID = Column('modelid', ForeignKey(Models.ModelID), nullable=False) Action = relationship(Actions) @@ -1058,10 +813,8 @@ class Simulations(Base): Unit = relationship(Units) -# Part of the Provenance table, needed here to meet dependancies +# Part of the Provenance table, needed here to meet dependencies class Citations(Base): - __tablename__ = u'citations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} CitationID = Column('citationid', Integer, primary_key=True, nullable=False) Title = Column('title', String(255), nullable=False) @@ -1069,21 +822,19 @@ class Citations(Base): PublicationYear = Column('publicationyear', Integer, nullable=False) CitationLink = Column('citationlink', String(255)) - def __repr__(self): - return "" % ( - self.CitationID, self.Title, self.Publisher, self.PublicationYear, self.CitationLink) - # ################################################################################ # Annotations # ################################################################################ class Annotations(Base): - __tablename__ = u'annotations' - - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} AnnotationID = Column('annotationid', Integer, primary_key=True, nullable=False) - AnnotationTypeCV = Column('annotationtypecv', ForeignKey(CVAnnotationType.Name), nullable=False, index=True) + 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) @@ -1092,13 +843,12 @@ class Annotations(Base): AnnotatorID = Column('annotatorid', ForeignKey(People.PersonID)) CitationID = Column('citationid', ForeignKey(Citations.CitationID)) - PersonObj = relationship(People) + # PersonObj = relationship(People) + AnnotatorObj = relationship(People) CitationObj = relationship(Citations) class ActionAnnotations(Base): - __tablename__ = u'actionannotations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) @@ -1108,9 +858,17 @@ class ActionAnnotations(Base): AnnotationObj = relationship(Annotations) +class EquipmentAnnotations(Base): + + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + EquipmentID = Column('valueid', BigInteger, ForeignKey(Equipment.EquipmentID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) + + AnnotationObj = relationship(Annotations) + EquipmentObj = relationship(Equipment) + + class MethodAnnotations(Base): - __tablename__ = u'methodannotations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) MethodID = Column('methodid', ForeignKey(Methods.MethodID), nullable=False) @@ -1121,8 +879,6 @@ class MethodAnnotations(Base): class ResultAnnotations(Base): - __tablename__ = u'resultannotations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) ResultID = Column('resultid', ForeignKey(Results.ResultID), nullable=False) @@ -1134,20 +890,7 @@ class ResultAnnotations(Base): ResultObj = relationship(Results) -class ResultValueAnnotations(Base): - __tablename__ = u'resultvalueannotations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - - BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) - ValueID = Column('valueid', BigInteger, nullable=False) - AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) - - AnnotationObj = relationship(Annotations) - - class SamplingFeatureAnnotations(Base): - __tablename__ = u'samplingfeatureannotations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), @@ -1162,8 +905,6 @@ class SamplingFeatureAnnotations(Base): # Data Quality # ################################################################################ class DataSetsResults(Base): - __tablename__ = u'datasetsresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) DataSetID = Column('datasetid', ForeignKey(DataSets.DataSetID), nullable=False) @@ -1174,8 +915,6 @@ class DataSetsResults(Base): class DataQuality(Base): - __tablename__ = 'dataquality' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} DataQualityID = Column('dataqualityid', Integer, primary_key=True, nullable=False) DataQualityTypeCV = Column('dataqualitytypecv', ForeignKey(CVDataQualityType.Name), nullable=False, @@ -1190,11 +929,14 @@ class DataQuality(Base): class ReferenceMaterials(Base): - __tablename__ = 'referencematerials' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ReferenceMaterialID = Column('referencematerialid', Integer, primary_key=True, nullable=False) - ReferenceMaterialMediumCV = Column('referencematerialmediumcv', ForeignKey(CVReferenceMaterialMedium.Name), nullable=False, index=True) + 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) @@ -1208,18 +950,22 @@ class ReferenceMaterials(Base): SamplingFeatureObj = relationship(SamplingFeatures) -# ResultNormalizationValues = Table( -# u'resultnormalizationvalues', Base.metadata, -# Column(u'resultid', ForeignKey(Results.ResultID), primary_key=True), -# Column(u'normalizedbyreferencematerialvalueid', ForeignKey('odm2.referencematerialvalues.referencematerialvalueid'), -# nullable=False), -# schema='odm2' -# ) +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 ReferenceMaterialValue(Base): - __tablename__ = u'referencematerialvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class ReferenceMaterialValues(Base): ReferenceMaterialValueID = Column('referencematerialvalueid', Integer, primary_key=True, nullable=False) ReferenceMaterialID = Column('referencematerialid', ForeignKey(ReferenceMaterials.ReferenceMaterialID), @@ -1234,20 +980,20 @@ class ReferenceMaterialValue(Base): ReferenceMaterialObj = relationship(ReferenceMaterials) UnitObj = relationship(Units) VariableObj = relationship(Variables) - #ResultsObj = relationship(Results, secondary=ResultNormalizationValues) + class ResultNormalizationValues(Base): - __tablename__ = 'resultnormalizationvalues' + ResultID = Column(u'resultid', ForeignKey(Results.ResultID), primary_key=True) - ReferenceMaterialValueID = Column(u'referencematerialvalueid', ForeignKey(ReferenceMaterialValue.ReferenceMaterialValueID), - nullable=False) + ReferenceMaterialValueID = Column(u'referencematerialvalueid', + ForeignKey(ReferenceMaterialValues.ReferenceMaterialValueID), + nullable=False) ResultsObj = relationship(Results) - ReferenceMaterialValueObj = relationship(ReferenceMaterialValue) + ReferenceMaterialValueObj = relationship(ReferenceMaterialValues) + class ResultsDataQuality(Base): - __tablename__ = 'resultsdataquality' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) ResultID = Column('resultid', ForeignKey(Results.ResultID), nullable=False) @@ -1261,8 +1007,6 @@ class ResultsDataQuality(Base): # Extension Properties # ################################################################################ class ExtensionProperties(Base): - __tablename__ = u'extensionproperties' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} PropertyID = Column('propertyid', Integer, primary_key=True, nullable=False) PropertyName = Column('propertyname', String(255), nullable=False) @@ -1275,8 +1019,6 @@ class ExtensionProperties(Base): class ActionExtensionPropertyValues(Base): - __tablename__ = u'actionextensionpropertyvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) @@ -1288,8 +1030,6 @@ class ActionExtensionPropertyValues(Base): class CitationExtensionPropertyValues(Base): - __tablename__ = u'citationextensionpropertyvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) @@ -1301,8 +1041,6 @@ class CitationExtensionPropertyValues(Base): class MethodExtensionPropertyValues(Base): - __tablename__ = u'methodextensionpropertyvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) MethodID = Column('methodid', ForeignKey(Methods.MethodID), nullable=False) @@ -1314,8 +1052,6 @@ class MethodExtensionPropertyValues(Base): class ResultExtensionPropertyValues(Base): - __tablename__ = u'resultextensionpropertyvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) ResultID = Column('resultid', ForeignKey(Results.ResultID), nullable=False) @@ -1327,8 +1063,6 @@ class ResultExtensionPropertyValues(Base): class SamplingFeatureExtensionPropertyValues(Base): - __tablename__ = u'samplingfeatureextensionpropertyvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), @@ -1341,8 +1075,6 @@ class SamplingFeatureExtensionPropertyValues(Base): class VariableExtensionPropertyValues(Base): - __tablename__ = u'variableextensionpropertyvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) VariableID = Column('variableid', ForeignKey(Variables.VariableID), nullable=False) @@ -1357,10 +1089,13 @@ class VariableExtensionPropertyValues(Base): # Extension Identifiers # ################################################################################ class ExternalIdentifierSystems(Base): - __tablename__ = u'externalidentifiersystems' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} - ExternalIdentifierSystemID = Column('externalidentifiersystemid', Integer, primary_key=True, nullable=False) + ExternalIdentifierSystemID = Column( + 'externalidentifiersystemid', + Integer, + primary_key=True, + nullable=False + ) ExternalIdentifierSystemName = Column('externalidentifiersystemname', String(255), nullable=False) IdentifierSystemOrganizationID = Column('identifiersystemorganizationid', ForeignKey(Organizations.OrganizationID), nullable=False) @@ -1369,16 +1104,8 @@ class ExternalIdentifierSystems(Base): IdentifierSystemOrganizationObj = relationship(Organizations) - def __repr__(self): - return "" % ( - self.ExternalIdentifierSystemID, self.ExternalIdentifierSystemName, - self.IdentifierSystemOrganizationID, self.ExternalIdentifierSystemDescription, - self.ExternalIdentifierSystemURL) - class CitationExternalIdentifiers(Base): - __tablename__ = u'citationexternalidentifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) @@ -1393,15 +1120,13 @@ class CitationExternalIdentifiers(Base): class MethodExternalIdentifiers(Base): - __tablename__ = u'methodexternalidentifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} 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)) @@ -1410,8 +1135,6 @@ class MethodExternalIdentifiers(Base): class PersonExternalIdentifiers(Base): - __tablename__ = u'personexternalidentifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) PersonID = Column('personid', ForeignKey(People.PersonID), nullable=False) @@ -1426,15 +1149,17 @@ class PersonExternalIdentifiers(Base): class ReferenceMaterialExternalIdentifiers(Base): - __tablename__ = u'referencematerialexternalidentifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} 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) + ReferenceMaterialExternalIdentifier = Column( + 'referencematerialexternalidentifier', + String(255), + nullable=False + ) ReferenceMaterialExternalIdentifierURI = Column('referencematerialexternalidentifieruri', String(255)) ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) @@ -1442,8 +1167,6 @@ class ReferenceMaterialExternalIdentifiers(Base): class SamplingFeatureExternalIdentifiers(Base): - __tablename__ = u'samplingfeatureexternalidentifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID), @@ -1451,7 +1174,11 @@ class SamplingFeatureExternalIdentifiers(Base): ExternalIdentifierSystemID = Column('externalidentifiersystemid', ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), nullable=False) - SamplingFeatureExternalIdentifier = Column('samplingfeatureexternalidentifier', String(255), nullable=False) + SamplingFeatureExternalIdentifier = Column( + 'samplingfeatureexternalidentifier', + String(255), + nullable=False + ) SamplingFeatureExternalIdentifierURI = Column('samplingfeatureexternalidentifieruri', String(255)) ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) @@ -1459,8 +1186,6 @@ class SamplingFeatureExternalIdentifiers(Base): class SpatialReferenceExternalIdentifiers(Base): - __tablename__ = u'spatialreferenceexternaledentifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID), @@ -1468,7 +1193,11 @@ class SpatialReferenceExternalIdentifiers(Base): ExternalIdentifierSystemID = Column('externalidentifiersystemid', ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), nullable=False) - SpatialReferenceExternalIdentifier = Column('spatialreferenceexternalidentifier', String(255), nullable=False) + SpatialReferenceExternalIdentifier = Column( + 'spatialreferenceexternalidentifier', + String(255), + nullable=False + ) SpatialReferenceExternalIdentifierURI = Column('spatialreferenceexternalidentifieruri', String(255)) ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) @@ -1476,8 +1205,6 @@ class SpatialReferenceExternalIdentifiers(Base): class TaxonomicClassifierExternalIdentifiers(Base): - __tablename__ = u'taxonomicclassifierexternalidentifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) TaxonomicClassifierID = Column('taxonomicclassifierid', @@ -1485,7 +1212,11 @@ class TaxonomicClassifierExternalIdentifiers(Base): ExternalIdentifierSystemID = Column('externalidentifiersystemid', ForeignKey(ExternalIdentifierSystems.ExternalIdentifierSystemID), nullable=False) - TaxonomicClassifierExternalIdentifier = Column('taxonomicclassifierexternalidentifier', String(255), nullable=False) + TaxonomicClassifierExternalIdentifier = Column( + 'taxonomicclassifierexternalidentifier', + String(255), + nullable=False + ) TaxonomicClassifierExternalIdentifierURI = Column('taxonomicclassifierexternalidentifieruri', String(255)) ExternalIdentifierSystemObj = relationship(ExternalIdentifierSystems) @@ -1493,8 +1224,6 @@ class TaxonomicClassifierExternalIdentifiers(Base): class VariableExternalIdentifiers(Base): - __tablename__ = u'variableexternalidentifiers' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) VariableID = Column('variableid', ForeignKey(Variables.VariableID), nullable=False) @@ -1513,8 +1242,6 @@ class VariableExternalIdentifiers(Base): # ################################################################################ class AuthorLists(Base): - __tablename__ = u'authorlists' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) @@ -1524,14 +1251,8 @@ class AuthorLists(Base): CitationObj = relationship(Citations, primaryjoin='AuthorLists.CitationID == Citations.CitationID') PersonObj = relationship(People, primaryjoin='AuthorLists.PersonID == People.PersonID') - def __repr__(self): - return "" \ - % (self.BridgeID, self.CitationID, self.PersonID, self.AuthorOrder, self.CitationObj, self.PersonObj) - class DataSetCitations(Base): - __tablename__ = u'datasetcitations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) DataSetID = Column('datasetid', ForeignKey(DataSets.DataSetID), nullable=False) @@ -1543,50 +1264,38 @@ class DataSetCitations(Base): DataSetObj = relationship(DataSets) -# ResultDerivationEquations = Table( -# u'resultderivationequations', Base.metadata, -# Column(u'resultid', ForeignKey(Results.ResultID), primary_key=True), -# Column(u'derivationequationid', ForeignKey('odm2.derivationequations.derivationequationid'), nullable=False), -# schema='odm2' -# ) - - class DerivationEquations(Base): - __tablename__ = u'derivationequations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} DerivationEquationID = Column('derivationequationid', Integer, primary_key=True, nullable=False) DerivationEquation = Column('derivationequation', String(255), nullable=False) - #ResultsObj = relationship(Results, secondary=ResultDerivationEquations) class ResultDerivationEquations(Base): - __tablename__ = u'resultderivationequations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ResultID = Column(u'resultid', ForeignKey(Results.ResultID), primary_key=True) - DerivationEquationID = Column(u'derivationequationid', ForeignKey(DerivationEquations.DerivationEquationID), nullable=False) + DerivationEquationID = Column( + u'derivationequationid', + ForeignKey(DerivationEquations.DerivationEquationID), + nullable=False + ) ResultsObj = relationship(Results) DerivationEquationsObj = relationship(DerivationEquations) + class MethodCitations(Base): - __tablename__ = u'methodcitations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} 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) -# from odm2.Annotations.model import Annotation class RelatedAnnotations(Base): - __tablename__ = u'relatedannotations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} RelationID = Column('relationid', Integer, primary_key=True, nullable=False) AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) @@ -1594,14 +1303,17 @@ class RelatedAnnotations(Base): 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') + AnnotationObj = relationship( + Annotations, + primaryjoin='RelatedAnnotations.AnnotationID == Annotations.AnnotationID' + ) + RelatedAnnotationObj = relationship( + Annotations, + primaryjoin='RelatedAnnotations.RelatedAnnotationID == Annotations.AnnotationID' + ) class RelatedCitations(Base): - __tablename__ = u'relatedcitations' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} RelationID = Column('relationid', Integer, primary_key=True, nullable=False) CitationID = Column('citationid', ForeignKey(Citations.CitationID), nullable=False) @@ -1610,13 +1322,13 @@ class RelatedCitations(Base): RelatedCitationID = Column('relatedcitationid', ForeignKey(Citations.CitationID), nullable=False) CitationObj = relationship(Citations, primaryjoin='RelatedCitations.CitationID == Citations.CitationID') - RelatedCitationObj = relationship(Citations, - primaryjoin='RelatedCitations.RelatedCitationID == Citations.CitationID') + RelatedCitationObj = relationship( + Citations, + primaryjoin='RelatedCitations.RelatedCitationID == Citations.CitationID' + ) class RelatedDataSets(Base): - __tablename__ = u'relateddatasets' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} RelationID = Column('relationid', Integer, primary_key=True, nullable=False) DataSetID = Column('datasetid', ForeignKey(DataSets.DataSetID), nullable=False) @@ -1626,12 +1338,13 @@ class RelatedDataSets(Base): VersionCode = Column('versioncode', String(50)) DataSetObj = relationship(DataSets, primaryjoin='RelatedDataSets.DataSetID == DataSets.DataSetID') - RelatedDataSetObj = relationship(DataSets, primaryjoin='RelatedDataSets.RelatedDataSetID == DataSets.DataSetID') + RelatedDataSetObj = relationship( + DataSets, + primaryjoin='RelatedDataSets.RelatedDataSetID == DataSets.DataSetID' + ) class RelatedResults(Base): - __tablename__ = u'relatedresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} RelationID = Column('relationid', Integer, primary_key=True, nullable=False) ResultID = Column('resultid', ForeignKey(Results.ResultID), nullable=False) @@ -1648,11 +1361,7 @@ class RelatedResults(Base): # ################################################################################ # Results # ################################################################################ - - -class PointCoverageResults(Base): - __tablename__ = u'pointcoverageresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class PointCoverageResults(Results): ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) ZLocation = Column('zlocation', Float(53)) @@ -1667,16 +1376,24 @@ class PointCoverageResults(Base): TimeAggregationInterval = Column('timeaggregationinterval', Float(53), nullable=False) TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', Integer, nullable=False) - XUnitObj = relationship(Units, primaryjoin='PointCoverageResults.IntendedXSpacingUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='PointCoverageResults.IntendedYSpacingUnitsID == Units.UnitsID') + IntendedXSpacingUnitsObj = relationship( + Units, + primaryjoin='PointCoverageResults.IntendedXSpacingUnitsID == Units.UnitsID' + ) + IntendedYSpacingUnitsObj = relationship( + Units, + primaryjoin='PointCoverageResults.IntendedYSpacingUnitsID == Units.UnitsID' + ) SpatialReferenceObj = relationship(SpatialReferences) - ZUnitObj = relationship(Units, primaryjoin='PointCoverageResults.ZLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='PointCoverageResults.ResultID == Results.ResultID') + ZLocationUnitsObj = relationship( + Units, + primaryjoin='PointCoverageResults.ZLocationUnitsID == Units.UnitsID' + ) + + __mapper_args__ = {'polymorphic_identity': 'Point coverage'} -class ProfileResults(Base): - __tablename__ = u'profileresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class ProfileResults(Results): ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) XLocation = Column('xlocation', Float(53)) @@ -1691,35 +1408,51 @@ class ProfileResults(Base): AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), nullable=False, index=True) - TimeUnitObj = relationship(Units, primaryjoin='ProfileResults.IntendedTimeSpacingUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='ProfileResults.IntendedZSpacingUnitsID == Units.UnitsID') + IntendedTimeSpacingUnitsObj = relationship( + Units, + primaryjoin='ProfileResults.IntendedTimeSpacingUnitsID == Units.UnitsID' + ) + IntendedZSpacingUnitsObj = relationship( + Units, + primaryjoin='ProfileResults.IntendedZSpacingUnitsID == Units.UnitsID' + ) SpatialReferenceObj = relationship(SpatialReferences) - XUnitObj = relationship(Units, primaryjoin='ProfileResults.XLocationUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='ProfileResults.YLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='ProfileResults.ResultID == Results.ResultID') + XLocationUnitsObj = relationship(Units, primaryjoin='ProfileResults.XLocationUnitsID == Units.UnitsID') + YLocationUnitsObj = relationship(Units, primaryjoin='ProfileResults.YLocationUnitsID == Units.UnitsID') + + __mapper_args__ = {'polymorphic_identity': 'Profile Coverage'} -class CategoricalResults(Base): - __tablename__ = u'categoricalresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class CategoricalResults(Results): ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) XLocation = Column('xlocation', Float(53)) - XLocationUnitsID = Column('xlocationunitsid', Integer) + XLocationUnitsID = Column('xlocationunitsid', Integer, ForeignKey(Units.UnitsID)) YLocation = Column('ylocation', Float(53)) - YLocationUnitsID = Column('ylocationunitsid', Integer) + YLocationUnitsID = Column('ylocationunitsid', Integer, ForeignKey(Units.UnitsID)) ZLocation = Column('zlocation', Float(53)) - ZLocationUnitsID = Column('zlocationunitsid', Integer) + 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) - ResultObj = relationship(Results, primaryjoin='CategoricalResults.ResultID == Results.ResultID') + 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(Base): - __tablename__ = u'transectresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} + +class TransectResults(Results): ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) ZLocation = Column('zlocation', Float(53)) @@ -1732,16 +1465,21 @@ class TransectResults(Base): AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), nullable=False, index=True) - TimeUnitObj = relationship(Units, primaryjoin='TransectResults.IntendedTimeSpacingUnitsID == Units.UnitsID') - TransectUnitObj = relationship(Units, primaryjoin='TransectResults.IntendedTransectSpacingUnitsID == Units.UnitsID') + IntendedTimeSpacingUnitsObj = relationship( + Units, + primaryjoin='TransectResults.IntendedTimeSpacingUnitsID == Units.UnitsID' + ) + IntendedTransectSpacingUnitsObj = relationship( + Units, + primaryjoin='TransectResults.IntendedTransectSpacingUnitsID == Units.UnitsID' + ) SpatialReferenceObj = relationship(SpatialReferences) - ZUnitObj = relationship(Units, primaryjoin='TransectResults.ZLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='TransectResults.ResultID == Results.ResultID') + ZLocationUnitsObj = relationship(Units, primaryjoin='TransectResults.ZLocationUnitsID == Units.UnitsID') + + __mapper_args__ = {'polymorphic_identity': 'Transect Coverage'} -class SpectraResults(Base): - __tablename__ = u'spectraresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class SpectraResults(Results): ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) XLocation = Column('xlocation', Float(53)) @@ -1756,17 +1494,19 @@ class SpectraResults(Base): AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), nullable=False, index=True) - WaveUnitObj = relationship(Units, primaryjoin='SpectraResults.IntendedWavelengthSpacingUnitsID == Units.UnitsID') + IntendedWavelengthSpacingUnitsObj = relationship( + Units, + primaryjoin='SpectraResults.IntendedWavelengthSpacingUnitsID == Units.UnitsID' + ) SpatialReferenceObj = relationship(SpatialReferences) - XUnitObj = relationship(Units, primaryjoin='SpectraResults.XLocationUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='SpectraResults.YLocationUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='SpectraResults.ZLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='SpectraResults.ResultID == Results.ResultID') + 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(Base): - __tablename__ = u'timeseriesresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} + +class TimeSeriesResults(Results): ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) XLocation = Column('xlocation', Float(53)) @@ -1781,50 +1521,58 @@ class TimeSeriesResults(Base): AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), nullable=False, index=True) - ResultObj = relationship(Results) - IntendedTimeSpacingUnitsObj = relationship(Units, - primaryjoin='TimeSeriesResults.IntendedTimeSpacingUnitsID == Units.UnitsID') + 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') - ResultObj = relationship(Results, primaryjoin='TimeSeriesResults.ResultID == Results.ResultID') - def __repr__(self): - return "" % \ - (self.ResultID, self.XLocation, self.YLocation, self.XLocation, - self.ResultObj, self.XLocationUnitsObj, self.SpatialReferenceObj, - self.IntendedTimeSpacing, self.AggregationStatisticCV) + __mapper_args__ = {'polymorphic_identity': 'Time series coverage'} -class SectionResults(Base): - __tablename__ = u'sectionresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +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('intendedxpacingunitsid', ForeignKey(Units.UnitsID)) + 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) - - TimeUnitObj = relationship(Units, primaryjoin='SectionResults.IntendedTimeSpacingUnitsID == Units.UnitsID') - XUnitObj = relationship(Units, primaryjoin='SectionResults.IntendedXSpacingUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='SectionResults.IntendedZSpacingUnitsID == 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) - YUnitObj = relationship(Units, primaryjoin='SectionResults.YLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='SectionResults.ResultID == Results.ResultID') + YLocationUnitsObj = relationship(Units, primaryjoin='SectionResults.YLocationUnitsID == Units.UnitsID') + + __mapper_args__ = {'polymorphic_identity': 'Section coverage'} -class TrajectoryResults(Base): - __tablename__ = u'trajectoryresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} +class TrajectoryResults(Results): ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) @@ -1835,16 +1583,20 @@ class TrajectoryResults(Base): AggregationStatisticCV = Column('aggregationstatisticcv', ForeignKey(CVAggregationStatistic.Name), nullable=False, index=True) - TimeUnitObj = relationship(Units, primaryjoin='TrajectoryResults.IntendedTimeSpacingUnitsID == Units.UnitsID') - TrajectoryUnitObj = relationship(Units, - primaryjoin='TrajectoryResults.IntendedTrajectorySpacingUnitsID == Units.UnitsID') + IntendedTimeSpacingUnitsObj = relationship( + Units, + primaryjoin='TrajectoryResults.IntendedTimeSpacingUnitsID == Units.UnitsID' + ) + IntendedTrajectorySpacingUnitsObj = relationship( + Units, + primaryjoin='TrajectoryResults.IntendedTrajectorySpacingUnitsID == Units.UnitsID' + ) SpatialReferenceObj = relationship(SpatialReferences) - ResultObj = relationship(Results, primaryjoin='TrajectoryResults.ResultID == Results.ResultID') + __mapper_args__ = {'polymorphic_identity': 'Trajectory coverage'} -class MeasurementResults(Base): - __tablename__ = u'measurementresults' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} + +class MeasurementResults(Results): ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) XLocation = Column('xlocation', Float(53)) @@ -1863,21 +1615,27 @@ class MeasurementResults(Base): nullable=False) SpatialReferenceObj = relationship(SpatialReferences) - TimeUnitObj = 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') - ResultObj = relationship(Results, primaryjoin='MeasurementResults.ResultID == Results.ResultID') - def __repr__(self): - return "" % \ - (self.ResultID, self.XLocation, self.YLocation, self.XLocation, - self.ResultObj, self.XLocationUnitsObj, self.SpatialReferenceObj, - self.AggregationStatisticCV) + 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): - __tablename__ = u'categoricalresultvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ValueID = Column('valueid', BigIntegerType, primary_key=True) ResultID = Column('resultid', ForeignKey(CategoricalResults.ResultID), nullable=False) @@ -1885,12 +1643,10 @@ class CategoricalResultValues(Base): ValueDateTime = Column('valuedatetime', DateTime, nullable=False) ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) - CategoricalResultObj = relationship(CategoricalResults) + ResultObj = relationship(CategoricalResults) class MeasurementResultValues(Base): - __tablename__ = u'measurementresultvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ValueID = Column('valueid', BigIntegerType, primary_key=True) ResultID = Column('resultid', ForeignKey(MeasurementResults.ResultID), nullable=False) @@ -1898,17 +1654,10 @@ class MeasurementResultValues(Base): ValueDateTime = Column('valuedatetime', DateTime, nullable=False) ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) - MeasurementResultObj = relationship(MeasurementResults) - - def __repr__(self): - return "" % (self.DataValue, self.ValueDateTime, self.ResultID) - - + ResultObj = relationship(MeasurementResults) class PointCoverageResultValues(Base): - __tablename__ = u'pointcoverageresultvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ValueID = Column('valueid', BigIntegerType, primary_key=True) ResultID = Column('resultid', ForeignKey(PointCoverageResults.ResultID), nullable=False) @@ -1922,14 +1671,18 @@ class PointCoverageResultValues(Base): CensorCodeCV = Column('censorcodecv', ForeignKey(CVCensorCode.Name), nullable=False, index=True) QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) - PointCoverageResultObj = relationship(PointCoverageResults) - XUnitObj = relationship(Units, primaryjoin='PointCoverageResultValues.XLocationUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='PointCoverageResultValues.YLocationUnitsID == Units.UnitsID') + ResultObj = relationship(PointCoverageResults) + XLocationUnitsObj = relationship( + Units, + primaryjoin='PointCoverageResultValues.XLocationUnitsID == Units.UnitsID' + ) + YLocationUnitsobj = relationship( + Units, + primaryjoin='PointCoverageResultValues.YLocationUnitsID == Units.UnitsID' + ) class ProfileResultValues(Base): - __tablename__ = u'profileresultvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ValueID = Column('valueid', BigIntegerType, primary_key=True) ResultID = Column('resultid', ForeignKey(ProfileResults.ResultID), nullable=False) @@ -1945,14 +1698,18 @@ class ProfileResultValues(Base): TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), nullable=False) - ProfileResultObj = relationship(ProfileResults) - TimeUnitObj = relationship(Units, primaryjoin='ProfileResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='ProfileResultValues.ZLocationUnitsID == Units.UnitsID') + ResultObj = relationship(ProfileResults) + TimeAggregationIntervalUnitsObj = relationship( + Units, + primaryjoin='ProfileResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID' + ) + ZLocationUnitsObj = relationship( + Units, + primaryjoin='ProfileResultValues.ZLocationUnitsID == Units.UnitsID' + ) class SectionResultValues(Base): - __tablename__ = u'sectionresultvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ValueID = Column('valueid', BigIntegerType, primary_key=True) ResultID = Column('resultid', ForeignKey(SectionResults.ResultID), nullable=False) @@ -1973,15 +1730,22 @@ class SectionResultValues(Base): TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), nullable=False) - SectionResultObj = relationship(SectionResults) - TimeUnitObj = relationship(Units, primaryjoin='SectionResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID') - XUnitObj = relationship(Units, primaryjoin='SectionResultValues.XLocationUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='SectionResultValues.ZLocationUnitsID == Units.UnitsID') + 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): - __tablename__ = u'spectraresultvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ValueID = Column('valueid', BigIntegerType, primary_key=True) ResultID = Column('resultid', ForeignKey(SpectraResults.ResultID), nullable=False) @@ -1997,14 +1761,20 @@ class SpectraResultValues(Base): TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), nullable=False) - SpectraResultObj = relationship(SpectraResults) - TimeUnitObj = relationship(Units, primaryjoin='SpectraResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID') - WavelengthUnitObj = relationship(Units, primaryjoin='SpectraResultValues.WavelengthUnitsID == Units.UnitsID') + ResultObj = relationship(SpectraResults) + TimeAggregationIntervalUnitsObj = relationship( + Units, + primaryjoin='SpectraResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID' + ) + + WavelengthUnitsObj = relationship( + Units, + primaryjoin='SpectraResultValues.WavelengthUnitsID == Units.UnitsID' + ) + class TimeSeriesResultValues(Base): - __tablename__ = u'timeseriesresultvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ValueID = Column('valueid', BigIntegerType, primary_key=True) ResultID = Column('resultid', ForeignKey(TimeSeriesResults.ResultID), nullable=False) @@ -2017,25 +1787,20 @@ class TimeSeriesResultValues(Base): TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), nullable=False) - TimeSeriesResultObj = relationship(TimeSeriesResults) - TimeUnitObj = relationship(Units) + ResultObj = relationship(TimeSeriesResults) + TimeAggregationIntervalUnitsObj = relationship(Units) def get_columns(self): - return ["ValueID", "ResultID", "DataValue", "ValueDateTime", "ValueDateTimeUTCOffset", - "CensorCodeCV", "QualityCodeCV", "TimeAggregationInterval", "TimeAggregationIntervalUnitsID"] + 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] - def __repr__(self): - return "" % (self.DataValue, self.ValueDateTime, self.TimeAggregationInterval) - class TrajectoryResultValues(Base): - __tablename__ = u'trajectoryresultvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ValueID = Column('valueid', BigIntegerType, primary_key=True) ResultID = Column('resultid', ForeignKey(TrajectoryResults.ResultID), nullable=False) @@ -2049,7 +1814,11 @@ class TrajectoryResultValues(Base): 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) + 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) @@ -2057,17 +1826,26 @@ class TrajectoryResultValues(Base): TimeAggregationIntervalUnitsID = Column('timeaggregationintervalunitsid', ForeignKey(Units.UnitsID), nullable=False) - TrajectoryResultObj = relationship(TrajectoryResults) - TimeUnitObj = relationship(Units, - primaryjoin='TrajectoryResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID') - XUnitObj = relationship(Units, primaryjoin='TrajectoryResultValues.XLocationUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='TrajectoryResultValues.YLocationUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='TrajectoryResultValues.ZLocationUnitsID == Units.UnitsID') + 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): - __tablename__ = u'transectresultvalues' - __table_args__ = {u'schema': 'odm2'} # __table_args__ = {u'schema': Schema.getSchema()} ValueID = Column('valueid', BigIntegerType, primary_key=True) ResultID = Column('resultid', ForeignKey(TransectResults.ResultID), nullable=False) @@ -2075,48 +1853,165 @@ class TransectResultValues(Base): ValueDateTime = Column('valuedatetime', DateTime, nullable=False) ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', DateTime, nullable=False) XLocation = Column('xlocation', Float(53), nullable=False) - XLocationUnitsID = Column('xlocationunitsid', Integer, nullable=False) + XLocationUnitsID = Column('xlocationunitsid', ForeignKey(Units.UnitsID), nullable=False) YLocation = Column('ylocation', Float(53), nullable=False) - YLocationUnitsID = Column('ylocationunitsid', Integer, 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', Integer, 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', Integer, 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', BigInteger, 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', BigInteger, 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', BigInteger, 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', BigInteger, 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', BigInteger, ForeignKey(SectionResultValues.ValueID), nullable=False) + AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) - TransectResultObj = relationship(TransectResults) + AnnotationObj = relationship(Annotations) + ValueObj = relationship(SectionResultValues) +class SpectraResultValueAnnotations(Base): + + BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) + ValueID = Column('valueid', BigInteger, 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', BigInteger, 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', BigInteger, 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', BigInteger, 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__) + # 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) - + insp = reflection.Inspector.from_engine(engine) for name in insp.get_schema_names(): - if 'odm2'== name.lower(): + if 'odm2' == name.lower(): return name - else: - return insp.default_schema_name + + return insp.default_schema_name + def setSchema(engine): s = _getSchema(engine) _changeSchema(s) - diff --git a/odm2api/ODM2/models_sqlite.py b/odm2api/ODM2/models_sqlite.py deleted file mode 100644 index bdbee01..0000000 --- a/odm2api/ODM2/models_sqlite.py +++ /dev/null @@ -1,2078 +0,0 @@ -from sqlalchemy import BigInteger, Column, Date, DateTime, Float, ForeignKey, Integer, String, Boolean, Table -from sqlalchemy.orm import relationship - -from sqlalchemy.dialects.sqlite import DATE - -# Should not be importing anything from a specific dialect -# from sqlalchemy.dialects.mssql.base import BIT - -from apiCustomType import Geometry -''' -from sqlalchemy.ext.declarative import declarative_base - -Base = declarative_base() -metadata = Base.metadata -''' - - -#from base import modelBase as Base - -from odm2api.base import modelBase -Base = modelBase.Base - -from sqlalchemy.dialects import postgresql, mysql, sqlite - -BigIntegerType = BigInteger() -BigIntegerType = BigIntegerType.with_variant(sqlite.INTEGER(), 'sqlite') -BigIntegerType = BigIntegerType.with_variant(postgresql.BIGINT(), 'postgresql') -BigIntegerType = BigIntegerType.with_variant(mysql.BIGINT(), 'mysql') - -################################################################################ -# CV -################################################################################ - - -class CVActionType(Base): - __tablename__ = 'cv_actiontype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVAggregationStatistic(Base): - __tablename__ = 'cv_aggregationstatistic' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % ( - self.Term, self.Name, self.Definition, self.Category) - - -class CVAnnotationType(Base): - __tablename__ = 'cv_annotationtype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVCensorCode(Base): - __tablename__ = 'cv_censorcode' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVDataQualityType(Base): - __tablename__ = 'cv_dataqualitytype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVDataSetType(Base): - __tablename__ = 'cv_datasettypecv' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVDeploymentType(Base): - __tablename__ = 'cv_deploymenttype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVDirectiveType(Base): - __tablename__ = 'cv_directivetype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVElevationDatum(Base): - __tablename__ = 'cv_elevationdatum' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVEquipmentType(Base): - __tablename__ = 'cv_equipmenttype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVMediumType(Base): - __tablename__ = 'cv_medium' -# # __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)) - def __repr__(self): - return "" %(self.Term, self.name, self.Definition, self.Category) - -class CVMethodType(Base): - __tablename__ = 'cv_methodtype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVOrganizationType(Base): - __tablename__ = 'cv_organizationtype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVPropertyDataType(Base): - __tablename__ = 'cv_propertydatatype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVQualityCode(Base): - __tablename__ = 'cv_qualitycode' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVResultType(Base): - __tablename__ = 'cv_resulttype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVRelationshipType(Base): - __tablename__ = 'cv_relationshiptype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - - -class CVSamplingFeatureGeoType(Base): - __tablename__ = 'cv_samplingfeaturegeotype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVSamplingFeatureType(Base): - __tablename__ = 'cv_samplingfeaturetype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVSpatialOffsetType(Base): - __tablename__ = 'cv_spatialoffsettype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVSpeciation(Base): - __tablename__ = 'cv_speciation' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVSpecimenType(Base): - __tablename__ = 'cv_specimentype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVSiteType(Base): - __tablename__ = 'cv_sitetype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVStatus(Base): - __tablename__ = 'cv_status' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVTaxonomicClassifierType(Base): - __tablename__ = 'cv_taxonomicclassifiertype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVUnitsType(Base): - __tablename__ = 'cv_unitstype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVVariableName(Base): - __tablename__ = 'cv_variablename' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -class CVVariableType(Base): - __tablename__ = 'cv_variabletype' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - -class CVReferenceMaterialMedium(Base): - __tablename__ = 'cv_referencematerialmedium' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % (self.Term, self.Name, self.Definition, self.Category) - - -# ################################################################################ -# Core -# ################################################################################ -class People(Base): - __tablename__ = u'people' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - def __repr__(self): - return "" % (self.PersonID, self.PersonFirstName, - self.PersonLastName) - - -class Organizations(Base): - __tablename__ = u'organizations' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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('organizations.organizationid')) - - OrganizationObj = relationship(u'Organizations', remote_side=[OrganizationID]) - - def __repr__(self): - return "" % ( - self.OrganizationID, self.OrganizationTypeCV, self.OrganizationCode, - self.OrganizationName, self.OrganizationDescription, self.OrganizationLink - ) - - -class Affiliations(Base): - __tablename__ = 'affiliations' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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, u'SQL_Latin1_General_CP1_CI_AS')) - #PrimaryEmail = Column('primaryemail', String(255, u'SQL_Latin1_General_CP1_CI_AS'), nullable=False) - #PrimaryAddress = Column('primaryaddress', String(255, u'SQL_Latin1_General_CP1_CI_AS')) - #PersonLink = Column('personlink', String(255, u'SQL_Latin1_General_CP1_CI_AS')) - 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): - __tablename__ = 'methods' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - MethodID = Column('methodid', Integer, primary_key=True, nullable=False) - MethodTypeCV = Column('methodtypecv', ForeignKey(CVMethodType.Name), nullable=False, index=True) - #MethodCode = Column('methodcode', String(50, u'SQL_Latin1_General_CP1_CI_AS'), nullable=False) - #MethodName = Column('methodname', String(255, u'SQL_Latin1_General_CP1_CI_AS'), nullable=False) - #MethodDescription = Column('methoddescription', String(500, u'SQL_Latin1_General_CP1_CI_AS')) - #MethodLink = Column('methodlink', String(255, u'SQL_Latin1_General_CP1_CI_AS')) - 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) - - def __repr__(self): - return "" \ - % (self.MethodID, self.MethodTypeCV, self.MethodCode, self.MethodName, self.MethodDescription, - self.MethodLink, self.OrganizationID) - - -class Actions(Base): - __tablename__ = u'actions' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - def __repr__(self): - return "" % ( - self.ActionID, self.ActionTypeCV, self.BeginDateTime, self.ActionDescription) - - -class ActionBy(Base): - __tablename__ = u'actionby' -# # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'samplingfeatures' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - SamplingFeatureID = Column('samplingfeatureid', Integer, primary_key=True, nullable=False) - SamplingFeatureUUID = Column('samplingfeatureuuid', String(36), nullable=False) - SamplingFeatureTypeCV = Column('samplingfeaturetypecv', ForeignKey(CVSamplingFeatureType.Name), - nullable=False, index=True) - SamplingFeatureCode = Column('samplingfeaturecode', String(50), nullable=False) - SamplingFeatureName = Column('samplingfeaturename', String(255)) - SamplingFeatureDescription = Column('samplingfeaturedescription', String(500)) - SamplingFeatureGeotypeCV = Column('samplingfeaturegeotypecv', ForeignKey(CVSamplingFeatureGeoType.Name), - index=True) - Elevation_m = Column('elevation_m', Float(53)) - ElevationDatumCV = Column('elevationdatumcv', ForeignKey(CVElevationDatum.Name), index=True) - #FeatureGeometry = Column('featuregeometry', Geometry) - - def __repr__(self): - return "" % ( - self.SamplingFeatureCode, self.SamplingFeatureName, self.SamplingFeatureDescription, - self.Elevation_m) # self.FeatureGeometry) - - -class FeatureActions(Base): - __tablename__ = u'featureactions' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - def __repr__(self): - return "" % (self.FeatureActionID, self.SamplingFeatureID, self.ActionID) - - -class DataSets(Base): - __tablename__ = u'datasets' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - def __repr__(self): - return "" % ( - self.DataSetID, self.DataSetTypeCV, self.DataSetCode, self.DataSetTitle, self.DataSetAbstract) - - -class ProcessingLevels(Base): - __tablename__ = u'processinglevels' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ProcessingLevelID = Column('processinglevelid', Integer, primary_key=True, nullable=False) - #ProcessingLevelCode = Column('processinglevelcode', String(50, u'SQL_Latin1_General_CP1_CI_AS'), nullable=False) - #Definition = Column('definition', String(500, u'SQL_Latin1_General_CP1_CI_AS')) - #Explanation = Column('explanation', String(500, u'SQL_Latin1_General_CP1_CI_AS')) - ProcessingLevelCode = Column('processinglevelcode', String(50), nullable=False) - Definition = Column('definition', String(500)) - Explanation = Column('explanation', String(500)) - - def __repr__(self): - return "" \ - % (self.ProcessingLevelID, self.ProcessingLevelCode, self.Definition, self.Explanation) - - -class RelatedActions(Base): - __tablename__ = u'relatedactions' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'taxonomicclassifiers' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - TaxonomicClassifierID = Column('taxonomicclassifierid', Integer, primary_key=True, nullable=False) - TaxonomicClassifierTypeCV = Column('taxonomicclassifiertypcv', ForeignKey(CVTaxonomicClassifierType.Name), - nullable=False, index=True) - #TaxonomicClassifierName = Column('taxonomicclassifiername', String(255, u'SQL_Latin1_General_CP1_CI_AS'), - # nullable=False) - #TaxonomicClassifierCommonName = Column('taxonomicclassifiercommonname', - # String(255, u'SQL_Latin1_General_CP1_CI_AS')) - #TaxonomicClassifierDescription = Column('taxonomicclassifierdescription', - # String(500, u'SQL_Latin1_General_CP1_CI_AS')) - TaxonomicClassifierName = Column('taxonomicclassifiername', String(255),nullable=False) - TaxonomicClassifierCommonName = Column('taxonomicclassifiercommonname',String(255)) - TaxonomicClassifierDescription = Column('taxonomicclassifierdescription',String(500)) - - ParentTaxonomicClassifierID = Column('parenttaxonomicclassifierid', - ForeignKey('taxonomicclassifiers.taxonomicclassifierid')) - - parent = relationship(u'TaxonomicClassifiers', remote_side=[TaxonomicClassifierID]) - - -class Units(Base): - __tablename__ = u'units' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % ( - self.UnitsID, self.UnitsTypeCV, self.UnitsAbbreviation, self.UnitsName) - - -class Variables(Base): - __tablename__ = u'variables' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - def __repr__(self): - return "" % (self.VariableID, self.VariableCode, self.VariableNameCV) - - -''' -class ResultTypeCV(Base): - __tablename__ = u'ResultTypeCV' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ResultTypeCV = Column(String(255), primary_key=True) - ResultTypeCategory = Column(String(255), nullable=False) - DataType = Column(String(255), nullable=False) - ResultTypeDefinition = Column(String(500), nullable=False) - FixedDimensions = Column(String(255), nullable=False) - VaryingDimensions = Column(String(255), nullable=False) - SpaceMeasurementFramework = Column(String(255), nullable=False) - TimeMeasurementFramework = Column(String(255), nullable=False) - VariableMeasurementFramework = Column(String(255), nullable=False) -''' - - -class Results(Base): - __tablename__ = u'results' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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', BigInteger) - ValidDateTime = Column('validdatetime', DateTime) - ValidDateTimeUTCOffset = Column('validdatetimeutcoffset', BigInteger) - StatusCV = Column('statuscv', ForeignKey(CVStatus.Name), index=True) - SampledMediumCV = Column('sampledmediumcv', ForeignKey(CVMediumType.Name), nullable=False, index=True) - ValueCount = Column('valuecount', Integer, nullable=False) - - # IntendedObservationSpacing = Column(String(255)) - - FeatureActionObj = relationship(FeatureActions) - ProcessingLevelObj = relationship(ProcessingLevels) - - TaxonomicClassifierObj = relationship(TaxonomicClassifiers) - UnitsObj = relationship(Units) - VariableObj = relationship(Variables) - - def __repr__(self): - return "" % ( - self.ResultID, self.ResultUUID, self.ResultTypeCV, self.ProcessingLevelID, self.ValueCount) - - -# ################################################################################ -# Equipment -# ################################################################################ -class EquipmentModels(Base): - __tablename__ = u'equipmentmodels' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ModelID = Column('modelid', Integer, primary_key=True, nullable=False) - ModelManufacturerID = Column('modelmanufacturerid', 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 Equipment(Base): - __tablename__ = u'equipment' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - EquipmentPhotoFileLink = Column('equipmentphotofilelink', String(255)) - EquipmentDescription = Column('equipmentdescription', String(500)) - ParentEquipmentID = Column('parentequipmentid', ForeignKey('equipment.equipmentid')) - - PersonObj = relationship(People) - OrganizationObj = relationship(Organizations) - EquipmentModelObj = relationship(EquipmentModels) - - parent = relationship(u'Equipment', remote_side=[EquipmentID]) - - -class EquipmentActions(Base): - __tablename__ = u'equipmentactions' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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 InstrumentOutputVariables(Base): - __tablename__ = u'instrumentoutputvariables' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - InstrumentOutputVariableID = Column('instrumentoutputvariableid', Integer, primary_key=True, nullable=False) - ModelID = Column('modelid', ForeignKey(EquipmentModels.ModelID), nullable=False) - VariableID = Column('variableid', ForeignKey(Variables.VariableID), nullable=False) - InstrumentMethodID = Column('instrumentmethodid', ForeignKey(Methods.MethodID), nullable=False) - InstrumentResolution = Column('instrumentresolution', String(255)) - InstrumentAccuracy = Column('instrumentaccuracy', String(255)) - InstrumentRawOutputUnitsID = Column('instrumentrawoutputunitsid', ForeignKey(Units.UnitsID), nullable=False) - - MethodObj = relationship(Methods) - OutputUnitObj = relationship(Units) - EquipmentModelObj = relationship(EquipmentModels) - VariableObj = relationship(Variables) - - -# ################################################################################ -# Lab Analyses -# ################################################################################ -class Directives(Base): - __tablename__ = u'directives' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'actiondirectives' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - -# ################################################################################ -# Sampling Features -# ################################################################################ -class SpatialReferences(Base): - __tablename__ = u'spatialreferences' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" \ - % (self.SpatialReferenceID, self.SRSCode, self.SRSName, self.SRSDescription, self.SRSLink) - - -class Specimens(Base): - __tablename__ = u'specimens' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - SamplingFeatureObj = relationship(SamplingFeatures) - - -class SpatialOffsets(Base): - __tablename__ = u'spatialoffsets' - # # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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(Base): - __tablename__ = u'sites' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - SamplingFeatureObj = relationship(SamplingFeatures) - - def __repr__(self): - return "" \ - % (self.SamplingFeatureID, self.SpatialReferenceID, self.SiteTypeCV, self.Latitude, self.Longitude, - self.SpatialReferenceObj, self.SamplingFeatureObj) - - -class RelatedFeatures(Base): - __tablename__ = u'relatedfeatures' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'specimentaxonomicclassifiers' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - -# ################################################################################ -# Sensors -# ################################################################################ -class DeploymentActions(Base): - __tablename__ = u'deploymentactions' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - DeploymentActionID = Column('deploymentactionid', Integer, primary_key=True, nullable=False) - ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) - DeploymentTypeCV = Column('deploymenttypecv', ForeignKey(CVDeploymentType.Name), nullable=False, index=True) - DeploymentDescription = Column('deploymentdescription', String(500)) - ConfigurationActionID = Column('configurationactionid', Integer, nullable=False) - CalibrationActionID = Column('calibrationactionid', Integer, nullable=False) - SpatialOffsetID = Column('spatialoffsetid', Integer) - DeploymentSchematicLink = Column('deploymentschematiclink', String(255)) - - ActionObj = relationship(Actions) - - -class DataLoggerFiles(Base): - __tablename__ = u'dataloggerfiles' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - DataLoggerFileID = Column('dataloggerfileid', Integer, primary_key=True, nullable=False) - DeploymentActionID = Column('actionid', ForeignKey(DeploymentActions.DeploymentActionID), nullable=False) - DataLoggerOutputFileLink = Column('dataloggeroutputfilelink', String(255), nullable=False) - DataLoggerOutputFileDescription = Column('dataloggeroutputfiledescription', String(500)) - - DeploymentActionObj = relationship(DeploymentActions) - - -class Photos(Base): - __tablename__ = u'photos' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - PhotoID = Column('photoid', Integer, primary_key=True, nullable=False) - ActionID = Column('actionid', ForeignKey(Actions.ActionID), nullable=False) - PhotoFileLink = Column('photofilelink', String(255), nullable=False) - PhotoDescription = Column('photodescription', String(500)) - - ActionObj = relationship(Actions) - - -# ################################################################################ -# Simulation -# ################################################################################ -class Models(Base): - __tablename__ = 'models' - # __table_args__ = {u'schema': 'odm2'} ## __table_args__ ={u'schema': Schema.getSchema()} - - 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): - __tablename__ = 'relatedmodels' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - RelationID = Column('relationid', 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): - __tablename__ = 'simulations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - 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 dependancies -class Citations(Base): - __tablename__ = u'citations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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)) - - def __repr__(self): - return "" % ( - self.CitationID, self.Title, self.Publisher, self.PublicationYear, self.CitationLink) - - -# ################################################################################ -# Annotations -# ################################################################################ -class Annotations(Base): - __tablename__ = u'annotations' - - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - CitationObj = relationship(Citations) - - -class ActionAnnotations(Base): - __tablename__ = u'actionannotations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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 MethodAnnotations(Base): - __tablename__ = u'methodannotations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'resultannotations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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 ResultValueAnnotations(Base): - __tablename__ = u'resultvalueannotations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - BridgeID = Column('bridgeid', Integer, primary_key=True, nullable=False) - ValueID = Column('valueid', BigInteger, nullable=False) - AnnotationID = Column('annotationid', ForeignKey(Annotations.AnnotationID), nullable=False) - - AnnotationObj = relationship(Annotations) - - -class SamplingFeatureAnnotations(Base): - __tablename__ = u'samplingfeatureannotations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'datasetsresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = 'dataquality' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - DataQualityID = Column('dataqualityid', Integer, primary_key=True, nullable=False) - DataQualityTypeCV = Column('dataqualitytypecv', ForeignKey(CVDataQualityType.Name), nullable=False, - index=True) - #DataQualityCode = Column('dataqualitycode', String(255, u'SQL_Latin1_General_CP1_CI_AS'), nullable=False) - DataQualityCode = Column('dataqualitycode', String(255), nullable=False) - DataQualityValue = Column('dataqualityvalue', Float(53)) - DataQualityValueUnitsID = Column('dataqualityvalueunitsid', ForeignKey(Units.UnitsID)) - #DataQualityDescription = Column('dataqualitydescription', String(500, u'SQL_Latin1_General_CP1_CI_AS')) - #DataQualityLink = Column('dataqualitylink', String(255, u'SQL_Latin1_General_CP1_CI_AS')) - DataQualityDescription = Column('dataqualitydescription', String(500)) - DataQualityLink = Column('dataqualitylink', String(255)) - - UnitObj = relationship(Units) - - -class ReferenceMaterials(Base): - __tablename__ = 'referencematerials' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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, u'SQL_Latin1_General_CP1_CI_AS'), nullable=False) - #ReferenceMaterialLotCode = Column('referencemateriallotcode', String(255, u'SQL_Latin1_General_CP1_CI_AS')) - 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, u'SQL_Latin1_General_CP1_CI_AS')) - ReferenceMaterialCertificateLink = Column('referencematerialcertificatelink', String(255)) - - SamplingFeatureID = Column('samplingfeatureid', ForeignKey(SamplingFeatures.SamplingFeatureID)) - - OrganizationObj = relationship(Organizations) - SamplingFeatureObj = relationship(SamplingFeatures) - -class ReferenceMaterialValue(Base): - __tablename__ = u'referencematerialvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = 'resultnormalizationvalues' - ResultID = Column(u'resultid', ForeignKey(Results.ResultID), primary_key=True) - ReferenceMaterialValueID = Column(u'referencematerialvalueid', ForeignKey(ReferenceMaterialValue.ReferenceMaterialValueID), - nullable=False) - - ResultsObj = relationship(Results) - ReferenceMaterialValueObj = relationship(ReferenceMaterialValue) - -class ResultsDataQuality(Base): - __tablename__ = 'resultsdataquality' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'extensionproperties' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'actionextensionpropertyvalues' - ## __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'citationextensionpropertyvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'methodextensionpropertyvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'resultextensionpropertyvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'samplingfeatureextensionpropertyvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'variableextensionpropertyvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'externalidentifiersystems' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - def __repr__(self): - return "" % ( - self.ExternalIdentifierSystemID, self.ExternalIdentifierSystemName, - self.IdentifierSystemOrganizationID, self.ExternalIdentifierSystemDescription, - self.ExternalIdentifierSystemURL) - - -class CitationExternalIdentifiers(Base): - __tablename__ = u'citationexternalidentifiers' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'methodexternalidentifiers' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'personexternalidentifiers' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'referencematerialexternalidentifiers' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'samplingfeatureexternalidentifiers' - ## __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'spatialreferenceexternaledentifiers' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'taxonomicclassifierexternalidentifiers' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'variableexternalidentifiers' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'authorlists' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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') - - def __repr__(self): - return "" \ - % (self.BridgeID, self.CitationID, self.PersonID, self.AuthorOrder, self.CitationObj, self.PersonObj) - - -class DataSetCitations(Base): - __tablename__ = u'datasetcitations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'derivationequations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - DerivationEquationID = Column('derivationequationid', Integer, primary_key=True, nullable=False) - DerivationEquation = Column('derivationequation', String(255), nullable=False) - -class ResultDerivationEquations(Base): - __tablename__ = u'resultderivationequations' - 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): - __tablename__ = u'methodcitations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - -# from odm2.Annotations.model import Annotation -class RelatedAnnotations(Base): - __tablename__ = u'relatedannotations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'relatedcitations' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'relateddatasets' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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): - __tablename__ = u'relatedresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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(Base): - __tablename__ = u'pointcoverageresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - XUnitObj = relationship(Units, primaryjoin='PointCoverageResults.IntendedXSpacingUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='PointCoverageResults.IntendedYSpacingUnitsID == Units.UnitsID') - SpatialReferenceObj = relationship(SpatialReferences) - ZUnitObj = relationship(Units, primaryjoin='PointCoverageResults.ZLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='PointCoverageResults.ResultID == Results.ResultID') - - -class ProfileResults(Base): - __tablename__ = u'profileresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - TimeUnitObj = relationship(Units, primaryjoin='ProfileResults.IntendedTimeSpacingUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='ProfileResults.IntendedZSpacingUnitsID == Units.UnitsID') - SpatialReferenceObj = relationship(SpatialReferences) - XUnitObj = relationship(Units, primaryjoin='ProfileResults.XLocationUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='ProfileResults.YLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='ProfileResults.ResultID == Results.ResultID') - - -class CategoricalResults(Base): - __tablename__ = u'categoricalresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ResultID = Column('resultid', ForeignKey(Results.ResultID), primary_key=True) - XLocation = Column('xlocation', Float(53)) - XLocationUnitsID = Column('xlocationunitsid', Integer) - YLocation = Column('ylocation', Float(53)) - YLocationUnitsID = Column('ylocationunitsid', Integer) - ZLocation = Column('zlocation', Float(53)) - ZLocationUnitsID = Column('zlocationunitsid', Integer) - SpatialReferenceID = Column('spatialreferenceid', ForeignKey(SpatialReferences.SpatialReferenceID)) - QualityCodeCV = Column('qualitycodecv', ForeignKey(CVQualityCode.Name), nullable=False, index=True) - - SpatialReferenceObj = relationship(SpatialReferences) - ResultObj = relationship(Results, primaryjoin='CategoricalResults.ResultID == Results.ResultID') - - -class TransectResults(Base): - __tablename__ = u'transectresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - TimeUnitObj = relationship(Units, primaryjoin='TransectResults.IntendedTimeSpacingUnitsID == Units.UnitsID') - TransectUnitObj = relationship(Units, primaryjoin='TransectResults.IntendedTransectSpacingUnitsID == Units.UnitsID') - SpatialReferenceObj = relationship(SpatialReferences) - ZUnitObj = relationship(Units, primaryjoin='TransectResults.ZLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='TransectResults.ResultID == Results.ResultID') - - -class SpectraResults(Base): - __tablename__ = u'spectraresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - WaveUnitObj = relationship(Units, primaryjoin='SpectraResults.IntendedWavelengthSpacingUnitsID == Units.UnitsID') - SpatialReferenceObj = relationship(SpatialReferences) - XUnitObj = relationship(Units, primaryjoin='SpectraResults.XLocationUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='SpectraResults.YLocationUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='SpectraResults.ZLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='SpectraResults.ResultID == Results.ResultID') - - -class TimeSeriesResults(Base): - __tablename__ = u'timeseriesresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - ResultObj = relationship(Results) - 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') - ResultObj = relationship(Results, primaryjoin='TimeSeriesResults.ResultID == Results.ResultID') - - def __repr__(self): - return "" % \ - (self.ResultID, self.XLocation, self.YLocation, self.XLocation, - self.ResultObj, self.XLocationUnitsObj, self.SpatialReferenceObj, - self.IntendedTimeSpacing, self.AggregationStatisticCV) - - -class SectionResults(Base): - __tablename__ = u'sectionresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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('intendedxpacingunitsid', 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) - - TimeUnitObj = relationship(Units, primaryjoin='SectionResults.IntendedTimeSpacingUnitsID == Units.UnitsID') - XUnitObj = relationship(Units, primaryjoin='SectionResults.IntendedXSpacingUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='SectionResults.IntendedZSpacingUnitsID == Units.UnitsID') - SpatialReferenceObj = relationship(SpatialReferences) - YUnitObj = relationship(Units, primaryjoin='SectionResults.YLocationUnitsID == Units.UnitsID') - ResultObj = relationship(Results, primaryjoin='SectionResults.ResultID == Results.ResultID') - - -class TrajectoryResults(Base): - __tablename__ = u'trajectoryresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - - TimeUnitObj = relationship(Units, primaryjoin='TrajectoryResults.IntendedTimeSpacingUnitsID == Units.UnitsID') - TrajectoryUnitObj = relationship(Units, - primaryjoin='TrajectoryResults.IntendedTrajectorySpacingUnitsID == Units.UnitsID') - SpatialReferenceObj = relationship(SpatialReferences) - ResultObj = relationship(Results, primaryjoin='TrajectoryResults.ResultID == Results.ResultID') - - -class MeasurementResults(Base): - __tablename__ = u'measurementresults' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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) - TimeUnitObj = 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') - ResultObj = relationship(Results, primaryjoin='MeasurementResults.ResultID == Results.ResultID') - def __repr__(self): - return "" % \ - (self.ResultID, self.XLocation, self.YLocation, self.XLocation, - self.ResultObj, self.XLocationUnitsObj, self.SpatialReferenceObj, - self.AggregationStatisticCV) - - -class CategoricalResultValues(Base): - __tablename__ = u'categoricalresultvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ValueID = Column('valueid', BigInteger, primary_key=True) - ResultID = Column('resultid', ForeignKey(CategoricalResults.ResultID), nullable=False) - DataValue = Column('datavalue', String(255), nullable=False) - ValueDateTime = Column('valuedatetime', DateTime, nullable=False) - ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) - - CategoricalResultObj = relationship(CategoricalResults) - - -class MeasurementResultValues(Base): - __tablename__ = u'measurementresultvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ValueID = Column('valueid', BigInteger, primary_key=True) - ResultID = Column('resultid', ForeignKey(MeasurementResults.ResultID), nullable=False) - DataValue = Column('datavalue', Float(53), nullable=False) - ValueDateTime = Column('valuedatetime', DateTime, nullable=False) - ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', Integer, nullable=False) - - MeasurementResultObj = relationship(MeasurementResults) - - def __repr__(self): - return "" % (self.DataValue, self.ValueDateTime, self.ResultID) - - - - -class PointCoverageResultValues(Base): - __tablename__ = u'pointcoverageresultvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ValueID = Column('valueid', BigInteger, primary_key=True) - ResultID = Column('resultid', ForeignKey(PointCoverageResults.ResultID), nullable=False) - DataValue = Column('datavalue', BigInteger, nullable=False) - ValueDateTime = Column('valuedatetime', DateTime, 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) - - PointCoverageResultObj = relationship(PointCoverageResults) - XUnitObj = relationship(Units, primaryjoin='PointCoverageResultValues.XLocationUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='PointCoverageResultValues.YLocationUnitsID == Units.UnitsID') - - -class ProfileResultValues(Base): - __tablename__ = u'profileresultvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ValueID = Column('valueid', BigInteger, primary_key=True) - ResultID = Column('resultid', ForeignKey(ProfileResults.ResultID), nullable=False) - DataValue = Column('datavalue', Float(53), nullable=False) - ValueDateTime = Column('valuedatetime', DateTime, 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) - - ProfileResultObj = relationship(ProfileResults) - TimeUnitObj = relationship(Units, primaryjoin='ProfileResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='ProfileResultValues.ZLocationUnitsID == Units.UnitsID') - - -class SectionResultValues(Base): - __tablename__ = u'sectionresultvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ValueID = Column('valueid', BigInteger, primary_key=True) - ResultID = Column('resultid', ForeignKey(SectionResults.ResultID), nullable=False) - DataValue = Column('datavalue', Float(53), nullable=False) - ValueDateTime = Column('valuedatetime', BigInteger, nullable=False) - ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', BigInteger, 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', BigInteger, 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) - - SectionResultObj = relationship(SectionResults) - TimeUnitObj = relationship(Units, primaryjoin='SectionResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID') - XUnitObj = relationship(Units, primaryjoin='SectionResultValues.XLocationUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='SectionResultValues.ZLocationUnitsID == Units.UnitsID') - - -class SpectraResultValues(Base): - __tablename__ = u'spectraresultvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ValueID = Column('valueid', BigInteger, primary_key=True) - ResultID = Column('resultid', ForeignKey(SpectraResults.ResultID), nullable=False) - DataValue = Column('datavalue', Float(53), nullable=False) - ValueDateTime = Column('valuedatetime', DateTime, 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) - - SpectraResultObj = relationship(SpectraResults) - TimeUnitObj = relationship(Units, primaryjoin='SpectraResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID') - WavelengthUnitObj = relationship(Units, primaryjoin='SpectraResultValues.WavelengthUnitsID == Units.UnitsID') - - -class TimeSeriesResultValues(Base): - __tablename__ = u'timeseriesresultvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - 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', DateTime, 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) - - TimeSeriesResultObj = relationship(TimeSeriesResults) - TimeUnitObj = 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] - - def __repr__(self): - return "" % (self.DataValue, self.ValueDateTime, self.TimeAggregationInterval) - - -class TrajectoryResultValues(Base): - __tablename__ = u'trajectoryresultvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ValueID = Column('valueid', BigInteger, primary_key=True) - ResultID = Column('resultid', ForeignKey(TrajectoryResults.ResultID), nullable=False) - DataValue = Column('datavalue', Float(53), nullable=False) - ValueDateTime = Column('valuedatetime', DateTime, 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) - - TrajectoryResultObj = relationship(TrajectoryResults) - TimeUnitObj = relationship(Units, - primaryjoin='TrajectoryResultValues.TimeAggregationIntervalUnitsID == Units.UnitsID') - XUnitObj = relationship(Units, primaryjoin='TrajectoryResultValues.XLocationUnitsID == Units.UnitsID') - YUnitObj = relationship(Units, primaryjoin='TrajectoryResultValues.YLocationUnitsID == Units.UnitsID') - ZUnitObj = relationship(Units, primaryjoin='TrajectoryResultValues.ZLocationUnitsID == Units.UnitsID') - - -class TransectResultValues(Base): - __tablename__ = u'transectresultvalues' - # __table_args__ = {u'schema': 'odm2'} # # __table_args__ = {u'schema': Schema.getSchema()} - - ValueID = Column('valueid', BigInteger, primary_key=True) - ResultID = Column('resultid', ForeignKey(TransectResults.ResultID), nullable=False) - DataValue = Column('datavalue', Float(53), nullable=False) - ValueDateTime = Column('valuedatetime', DateTime, nullable=False) - ValueDateTimeUTCOffset = Column('valuedatetimeutcoffset', DateTime, nullable=False) - XLocation = Column('xlocation', Float(53), nullable=False) - XLocationUnitsID = Column('xlocationunitsid', Integer, nullable=False) - YLocation = Column('ylocation', Float(53), nullable=False) - YLocationUnitsID = Column('ylocationunitsid', Integer, nullable=False) - TransectDistance = Column('transectdistance', Float(53), nullable=False) - TransectDistanceAggregationInterval = Column('transectdistanceaggregationinterval', Float(53), nullable=False) - TransectDistanceUnitsID = Column('transectdistanceunitsid', Integer, 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', Integer, nullable=False) - - TransectResultObj = relationship(TransectResults) - - -import inspect -import sys - -def change_schema(schema): - #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: - Tbl.__table__.schema = schema diff --git a/odm2api/ODM2/services/__init__.py b/odm2api/ODM2/services/__init__.py index e7064de..ecdd49a 100644 --- a/odm2api/ODM2/services/__init__.py +++ b/odm2api/ODM2/services/__init__.py @@ -1,46 +1,15 @@ -__author__ = 'jmeline' -''' -from createService import createAnnotations, createCore, createCV, createDataQuality, createEquipment, \ - createExtensionProperties, createExternalIdentifiers, createLabAnalyses, createODM2, createProvenance, \ - createResults, createSamplingFeatures, createSensors, createSimulation - -from deleteService import deleteAnnotations, deleteCore, deleteCV, deleteDataQuality, deleteEquipment, \ - deleteExtensionProperties, deleteExternalIdentifiers, deleteLabAnalyses, deleteODM2, deleteProvenance, \ - deleteResults, deleteSamplingFeatures, deleteSensors +from __future__ import (absolute_import, division, print_function) -from readService import readAnnotations, readCore, readCV, readDataQuality, readEquipment, readExtensionProperties, \ - readExternalIdentifiers, readODM2, readLabAnalyses, readProvenance, readResults, readSamplingFeatures, \ - readSensors, readSimulation +from odm2api.ODM2.services.createService import CreateODM2 +from odm2api.ODM2.services.deleteService import DeleteODM2 +from odm2api.ODM2.services.readService import ReadODM2 +from odm2api.ODM2.services.updateService import UpdateODM2 -from updateService import updateAnnotations, updateCore, updateCV, updateDataQuality, updateEquipment, \ - updateExtensionProperties, updateExternalIdentifiers, updateLabAnalyses, updateODM2, updateProvenance, \ - updateResults, updateSamplingFeatures, updateSensors +__author__ = 'jmeline' __all__ = [ - # Create - 'createAnnotations', 'createCore', 'createCV', 'createDataQuality', 'createEquipment', 'createExtensionProperties', - 'createExternalIdentifiers', 'createLabAnalyses', 'createODM2', 'createProvenance', 'createResults', - 'createSamplingFeatures', 'createSensors', 'createSimulation', - - # Delete - 'deleteSensors', 'deleteAnnotations', 'deleteCore', 'deleteCV', 'deleteDataQuality', 'deleteEquipment', - 'deleteExtensionProperties', 'deleteExternalIdentifiers', 'deleteLabAnalyses', 'deleteODM2', 'deleteProvenance', - 'deleteResults', 'deleteSamplingFeatures', - - # Read - 'readAnnotations', 'readCore', 'readCV', 'readDataQuality', 'readEquipment', 'readExtensionProperties', - 'readExternalIdentifiers', 'readLabAnalyses', 'readODM2', 'readProvenance', 'readResults', 'readSamplingFeatures', - 'readSensors', 'readSimulation', - - # Update - 'updateAnnotations', 'updateSensors', 'updateSamplingFeatures', 'updateResults', 'updateProvenance', 'updateODM2', - 'updateLabAnalyses', 'updateExternalIdentifiers', 'updateCore', 'updateCV', 'updateDataQuality', 'updateEquipment', - 'updateExtensionProperties' + 'CreateODM2', + 'DeleteODM2', + 'ReadODM2', + 'UpdateODM2' ] -''' -from createService import CreateODM2 -from deleteService import DeleteODM2 -from readService import ReadODM2 -from updateService import UpdateODM2 - -__all__= ['CreateODM2', 'DeleteODM2', 'ReadODM2', 'UpdateODM2' ] \ No newline at end of file diff --git a/odm2api/ODM2/services/createService.py b/odm2api/ODM2/services/createService.py index 1f5309c..1fceb2f 100644 --- a/odm2api/ODM2/services/createService.py +++ b/odm2api/ODM2/services/createService.py @@ -1,658 +1,154 @@ -__author__ = 'sreeder' +from __future__ import (absolute_import, division, print_function) -import datetime as dt import uuid -#from src.api.ODM2.LikeODM1.model import Site -from odm2api.ODM2.models import * from odm2api.ODM2 import serviceBase +from odm2api.ODM2.models import TimeSeriesResultValues - -class CreateODM2( serviceBase): - ''' - def __init__(self, session): - self._session = session - ''' -# ################################################################################ -# Annotations -# ################################################################################ - - - -# ################################################################################ -# CV -# ################################################################################ - - +__author__ = 'sreeder' -# ################################################################################ -# Core -# ################################################################################ +class CreateODM2(serviceBase): + # Annotations - def createVariable(self, code, name, vType, nodv, speciation=None, definition=None): - """ + def create(self, value): + self._session.add(value) + self._session.commit() + return value - :param code: - :type String(50): - :param name: - :type String(255): - :param vType: - :type String(255): - :param nodv: - :type Float(53): - :param speciation: - :type String(255): - :param definition: - :type String(500): - :return: - """ - var = Variables() - var.VariableCode = code - var.VariableNameCV = name - var.VariableDefinition = definition - var.VariableTypeCV = vType - var.NoDataValue = nodv - var.SpeciationCV = speciation + 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, code, name, vType, orgId=None, link=None, description=None): - """Create Method table for the database - - :param code: - :type String(50): - :param name: - :type String(255): - :param vType: - :type String(255): - :param orgId: - :type Integer: - :param link: - :type String(255): - :param description: - :type String(500): - :return: - """ - - meth = Methods() - meth.MethodCode = code - meth.MethodName = name - meth.MethodDescription = description - meth.MethodTypeCV = vType - meth.MethodLink = link - meth.OrganizationID = orgId - - self._session.add(meth) + def createMethod(self, method): + self._session.add(method) self._session.commit() + return method - return meth - - def createProcessingLevel(self, code, definition=None, explanation=None): - """Create Processinglevel table for database - - :param code: - :type String(50): - :param definition: - :type String(500): - :param explanation: - :type String(500): - :return: - """ - pl = ProcessingLevels() - pl.ProcessingLevelCode = str(code) - pl.Definition = definition - pl.Explanation = explanation - - self._session.add(pl) + def createProcessingLevel(self, proclevel): + self._session.add(proclevel) self._session.commit() + return proclevel - return pl - - def createSamplingFeature(self, uuid, code, vType, name=None, description=None, geoType=None, elevation=None, - elevationDatum=None, featureGeo=None): - """Create SamplingFeature table - - :param code: - :type String(50): - :param vType: - :type String(255): - :param name: - :type String(255): - :param description: - :type String(500): - :param geoType: - :type String(255): - :param evelation: - :type Float(53): - :param evelationDatum: - :type String(255): - :param featureGeo: - :type NullType: - :return: - """ - - sf = SamplingFeatures() - sf.SamplingFeatureUUID = uuid - sf.SamplingFeatureTypeCV = vType - sf.SamplingFeatureCode = code - sf.SamplingFeatureName = name - sf.SamplingFeatureDescription = description - sf.SamplingFeatureGeoTypeCV = geoType - sf.Elevation_m = elevation - sf.ElevationDatumCV = elevationDatum - sf.FeatureGeometry = featureGeo - - self._session.add(sf) + def createSamplingFeature(self, samplingfeature): + if samplingfeature.SamplingFeatureUUID is None: + samplingfeature.SamplingFeatureUUID = str(uuid.uuid1()) + self._session.add(samplingfeature) self._session.commit() + return samplingfeature - return sf - - - def createUnit(self, type, abbrev, name, link=None): - """Create Unit table - - :param code: - :type String(255): - :param abbrev: - :type String(50): - :param name: - :type String(255): - :return: - """ - unit = Units() - unit.UnitsTypeCV = type - unit.UnitsAbbreviation = abbrev - unit.UnitsName = name - unit.UnitsLink = link - + def createUnit(self, unit): self._session.add(unit) self._session.commit() - return unit - def createOrganization(self, cvType, code, name, desc, link, parentOrgId): - """Create Organization table - - :param cvType: - :type String(255): - :param code: - :type String(50): - :param name: - :type String(255): - :param desc: - :type String(500): - :param link: - :type String(255): - :param parentOrgId: - :type Integer: - :return: - """ - - org = Organizations() - org.OrganizationTypeCV = cvType - org.OrganizationCode = code - org.OrganizationName = name - org.OrganizationDescription = desc - org.OrganizationLink = link - org.ParentOrganizationID = parentOrgId - + def createOrganization(self, org): self._session.add(org) self._session.commit() - return org - def createPerson(self, firstName, lastName, middleName=""): - """Create Person Table - - :param firstName: - :type String(255): - :param lastName: - :type String(255): - :param middleName: - :type String(255): - :return: - """ - - p = People() - p.PersonFirstName = firstName - p.PersonMiddleName = middleName - p.PersonLastName = lastName - - self._session.add(p) + def createPerson(self, person): + self._session.add(person) self._session.commit() + return person - return p - - # def createResult(self, uuid, featureActionId, vType, ): - - def createAffiliation(self, personid, organizationid, email, phone=None, address=None, link=None, - iscontact=False, affiliation_start=dt.datetime.today(), affiliation_end=None): - """ - - :param personid: id of the person record - :param organizationid: id of the organization record - :param email: primary email address - :param phone: primary phone number - :param address: primary mailing address - :param link: url pointing the web resource such as researchGate profile - :param iscontact: indicate if this person is the primary contact for the organization - :param affiliation_start: begin date of affiliation with organization - :param affiliation_end: end date of affiliation with organization - :return: ODM2.Affiliation - """ - - # create affiliation object - a = Affiliations() - a.PersonID = personid - a.OrganizationID = organizationid - a.PrimaryEmail = email - a.PrimaryPhone = phone - a.PrimaryAddress = address - a.PersonLink = link - a.IsPrimaryOrganizationContact = iscontact - a.AffiliationStartDate = affiliation_start - a.AffiliationEndDate = affiliation_end - - self._session.add(a) + def createAffiliation(self, affiliation): + self._session.add(affiliation) self._session.commit() - #self._session.flush() - # self._session.refresh(a) - - print(a.OrganizationID) + return affiliation - return a - - def createDataset(self, dstype, dscode, dstitle, dsabstract): - ds = DataSets() - - # create the dataset - ds.DataSetTypeCV = dstype - ds.DataSetCode = dscode - ds.DataSetTitle = dstitle - ds.DataSetAbstract = dsabstract - ds.DataSetUUID = uuid.uuid4().hex - - self._session.add(ds) + def createDataset(self, dataset): + self._session.add(dataset) self._session.commit() + return dataset - return ds - - def createDatasetResults(self, dsid, resultid): - dsr = DataSetsResults() - - # link dataset to results - dsr.DatasetID = dsid - dsr.ResultID = resultid - - self._session.add(dsr) + def createDatasetResults(self, datasetresult): + self._session.add(datasetresult) self._session.commit() + return datasetresult - return dsr - - def createAction(self, type, methodid, begindatetime, begindatetimeoffset, enddatetime=None, enddatetimeoffset=None, - description=None, filelink=None): - action = Actions() - action.ActionTypeCV = type - action.MethodID = methodid - action.BeginDateTime = begindatetime - action.BeginDateTimeUTCOffset = begindatetimeoffset - action.EndDateTime = enddatetime - action.EndDateTimeUTCOffset = enddatetimeoffset - action.ActionDescription = description - action.ActionFileLink = filelink - + def createAction(self, action): self._session.add(action) self._session.commit() - return action - def createActionBy(self, actionid, affiliationid, isactionlead=True, roledescription=None): - actionby = ActionBy() - actionby.ActionID = actionid - actionby.AffiliationID = affiliationid - actionby.IsActionLead = isactionlead - actionby.RoleDescription = roledescription + def createActionby(self, actionby): self._session.add(actionby) self._session.commit() - return actionby - def createFeatureAction(self, samplingfeatureid, actionid): - featureaction = FeatureActions() - featureaction.SamplingFeatureID = samplingfeatureid - featureaction.ActionID = actionid + def createFeatureAction(self, action): + self._session.add(action) + self._session.commit() + return action - self._session.add(featureaction) + def createAnnotations(self, anno): + self._session.add(anno) self._session.commit() + return anno - return featureaction - - - def createResult(self, featureactionid, variableid, unitid, processinglevelid, valuecount, sampledmedium, - resulttypecv, - taxonomicclass=None, resultdatetime=None, resultdatetimeutcoffset=None, - validdatetime=None, validdatetimeutcoffset=None, statuscv=None): - result = Results() - #result.ResultUUID = uuid.uuid4().hex - result.ResultUUID = str(uuid.uuid4()) # Denver - result.FeatureActionID = featureactionid - result.ResultTypeCV = resulttypecv - result.VariableID = variableid - result.UnitsID = unitid - result.ProcessingLevelID = processinglevelid - result.ValueCount = valuecount - result.SampledMediumCV = sampledmedium - result.TaxonomicClassifierID = taxonomicclass - result.ResultDateTime = resultdatetime - result.ResultDateTimeUTCOffset = resultdatetimeutcoffset - result.ValidDateTime = validdatetime - result.ValidDateTimeUTCOffset = validdatetimeutcoffset - result.StatusCV = statuscv + 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 -# ################################################################################ -# Data Quality -# ################################################################################ - - - -# ################################################################################ -# Equipment -# ################################################################################ - - - - -# ################################################################################ -# ExtensionProperties -# ################################################################################ - - - - - -# ################################################################################ -# External Identifiers -# ################################################################################ - - - - -# ################################################################################ -# Lab Analyses -# ################################################################################ - - - - -# ################################################################################ -# Provenance -# ################################################################################ - - - - -# ################################################################################ -# Results -# ################################################################################ - - - - def createTimeSeriesResult(self, result, aggregationstatistic, xloc=None, xloc_unitid=None, yloc=None, - yloc_unitid=None, zloc=None, zloc_unitid=None, - srsID=None, timespacing=None, timespacing_unitid=None): - - tsr = TimeSeriesResults() - - tsr.ResultID = result.ResultID - #tsr.ResultUUID = result.ResultUUID - - - tsr.XLocation = xloc - tsr.XLocationUnitsID = xloc_unitid - tsr.YLocation = yloc - tsr.YLocationUnitsID = yloc_unitid - tsr.ZLocation = zloc - tsr.ZLocationUnitsID = zloc_unitid - tsr.SpatialReferenceID = srsID - tsr.IntendedTimeSpacing = timespacing - tsr.IntendedTimeSpacingUnitsID = timespacing_unitid - tsr.AggregationStatisticCV = aggregationstatistic - - - #tsr.ResultID = result.ResultID - # tsr.ResultUUID = result.ResultUUID - # tsr.FeatureActionID = result.FeatureActionID - # tsr.VariableID = result.VariableID - # tsr.UnitsID = result.UnitsID - # tsr.ProcessingLevelID = result.ProcessingLevelID - # tsr.ValueCount = result.ValueCount - # tsr.SampledMediumCV = result.SampledMediumCV - # tsr.ResultTypeCV = result.ResultTypeCV + def createSpatialReference(self, spatialref): + self._session.add(spatialref) + self._session.commit() + return spatialref - self._session.add(tsr) + def createModel(self, model): + self._session.add(model) self._session.commit() - return tsr - ''' - def createTimeSeriesResultValues(self, resultid, datavalues, datetimes, datetimeoffsets, censorcodecv, - qualitycodecv, - timeaggregationinterval, timeaggregationunit): + return model + def createRelatedModel(self, relatedmodel): + self._session.add(relatedmodel) + self._session.commit() + return relatedmodel - try: - values = TimeSeriesResultValues() - for i in range(len(datavalues)): - values.ResultID = resultid - values.CensorCodeCV = censorcodecv - values.QualityCodeCV = qualitycodecv - values.TimeAggregationInterval = timeaggregationinterval - values.TimeAggregationIntervalUnitsID = timeaggregationunit - values.DataValue = datavalues[i] - values.ValueDateTime = datetimes[i] - values.ValueDateTimeUTCOffset = datetimeoffsets[i] - self._session.add(values) - self._session.commit() - return values - except Exception, e: - print e - return None - ''' + def createSimulation(self, simulation): + self._session.add(simulation) + self._session.commit() + return simulation def createTimeSeriesResultValues(self, datavalues): try: - #using Pandas built-in --slow - #changing way values sent --unknown error on insert - #cols = datavalues.columns.tolist() - #['ValueDateTime', 'DataValue', 'TimeAggregationInterval', 'TimeAggregationIntervalUnitsID', 'QualityCodeCV', 'CensorCodeCV', 'ResultID', 'ValueDateTimeUTCOffset'] - #cols = ['ResultID','DataValue','ValueDateTime','ValueDateTimeUTCOffset','CensorCodeCV','QualityCodeCV','TimeAggregationInterval','TimeAggregationIntervalUnitsID'] - #datavalues = datavalues[cols] - #print datavalues - #datavalues.to_sql(name=TimeSeriesResultValues.__tablename__, - datavalues.to_sql(name="TimeSeriesResultValues", - schema=TimeSeriesResultValues.__table_args__['schema'], - if_exists='append', - chunksize= 1000, - con=self._session_factory.engine, - index=False) + # 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() - - #using sqlalchemy core --sending empty parameters - # data = datavalues.to_dict('records') - # self._session.execute(TimeSeriesResultValues.__table__.insert(data)) - - #using cursor and StringIO --not all cursors have the copy_from function - # print "using cursor" - # import cStringIO - # #stream the data using 'to_csv' and StringIO(); then use sql's 'copy_from' function - # output = cStringIO.StringIO() - # #ignore the index - # datavalues.to_csv(output, sep='\t', header=False, index=False) - # #jump to start of stream - # output.seek(0) - # contents = output.getvalue() - # connection = self._session_factory.engine.raw_connection() - # cur = connection.cursor() - # #null values become '' - # cur.copy_from(output, 'ODM2.TimeSeriesResultValues', null="") - # connection.commit() - # cur.close() - - #using Bulk Insert * user must have permissions --file created locally code running remote - # datavalues.to_csv('C:\\Users\\Stephanie\\temp.csv') - # sql = """ - # BULK INSERT ODM2.TimeSeriesResultValues - # FROM 'C:\\Users\\Stephanie\\temp.csv' WITH ( - # FIELDTERMINATOR=',', - # ROWTERMINATOR='\\n'); - # """ - # self._session.execute(sql) - - - - return datavalues except Exception as e: print(e) return None - - -# ################################################################################ -# Sampling Features -# ################################################################################ - - - def createSite(self, sfId, spatialRefId, vType, latitude, longitude): - """Create Site table - - :param vType: - :type String(255): - :param latitude: - :type Float(53): - :param longitude: - :type Float(53): - :return: - """ - - s = Sites() - s.SamplingFeatureID = sfId - s.SpatialReferenceID = spatialRefId - s.SiteTypeCV = vType - s.Latitude = latitude - s.Longitude = longitude - - self._session.add(s) - self._session.commit() - - return s - - - def createSpatialReference(self, srsCode, srsName, srsDescription=None): - spatialreference = SpatialReferences() - spatialreference.SRSCode = srsCode - spatialreference.SRSName = srsName - spatialreference.SRSDescription = srsDescription - - self._session.add(spatialreference) - self._session.commit() - - return spatialreference - - -# ################################################################################ -# Sensors -# ################################################################################ - - def createDeploymentAction(self, actionId, cvType, desc, configActionId, calibActionId, spatialOffSet, - deploymentSchematicLink, **kwargs): - """Create DeploymentAction Object - - :param **kwargs: - :param actionId: - :type Integer: - :param cvType: - :type String(255): - :param desc: - :type String(500): - :param configActionId: - :type Integer: - :param calibActionId: - :type Integer: - :param spatialOffSet: - :type Integer: - :param deploymentSchematicLink: - :type String(255): - :return: - """ - - da = DeploymentActions() - da.ActionID = (kwargs['actionId'] if kwargs['actionId'] else None) - da.ActionID = (kwargs['actionId'] if kwargs['actionId'] else None) - da.ActionID = (kwargs['actionId'] if kwargs['actionId'] else None) - da.ActionID = (kwargs['actionId'] if kwargs['actionId'] else None) - da.ActionID = (kwargs['actionId'] if kwargs['actionId'] else None) - da.ActionID = (kwargs['actionId'] if kwargs['actionId'] else None) - - -# ################################################################################ -# Simulation -# ################################################################################ - - - def createModel(self, code, name, description=None): - model = Models() - model.ModelCode = code - model.ModelName = name - model.ModelDescription = description - - self._session.add(model) - self._session.commit() - - return model - - - def createRelatedModel(self, modelid, relatedModelID, relationshipType): - related = RelatedModels() - related.ModelID = modelid - related.RelationshipTypeCV = relationshipType - related.RelatedModelID = relatedModelID - - self._session.add(related) - self._session.commit() - - return related - - - def createSimulation(self, actionid, modelID, simulationName, simulationDescription, simulationStartDateTime, - simulationStartOffset, - simulationEndDateTime, simulationEndOffset, timeStepValue, timeStepUnitID, - inputDatasetID=None): - sim = Simulations() - sim.ActionID = actionid - sim.ModelID = modelID - sim.SimulationName = simulationName - sim.SimulationDescription = simulationDescription - sim.SimulationStartDateTime = simulationStartDateTime - sim.SimulationStartDateTimeUTCOffset = simulationStartOffset - sim.SimulationEndDateTime = simulationEndDateTime - sim.SimulationEndDateTimeUTCOffset = simulationEndOffset - sim.TimeStepValue = timeStepValue - sim.TimeStepUnitsID = timeStepUnitID - sim.InputDatasetID = inputDatasetID - - self._session.add(sim) - self._session.commit() - - return sim - diff --git a/odm2api/ODM2/services/deleteService.py b/odm2api/ODM2/services/deleteService.py index d732739..43f944a 100644 --- a/odm2api/ODM2/services/deleteService.py +++ b/odm2api/ODM2/services/deleteService.py @@ -1,95 +1,42 @@ -__author__ = 'jmeline' +from __future__ import (absolute_import, division, print_function) from odm2api.ODM2 import serviceBase -from odm2api.ODM2.models import * - -# ################################################################################ -# Annotations -# ################################################################################ +from odm2api.ODM2.models import TimeSeriesResultValues -class DeleteODM2(serviceBase): - def test(self): - return None - -# ################################################################################ -# CV -# ################################################################################ +__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 -# ################################################################################ - - - - -# ################################################################################ -# ODM2 -# ################################################################################ - +# 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/ODM2/services/readService.py b/odm2api/ODM2/services/readService.py index 0628d95..5816127 100644 --- a/odm2api/ODM2/services/readService.py +++ b/odm2api/ODM2/services/readService.py @@ -1,982 +1,1116 @@ -__author__ = 'jmeline' +from __future__ import (absolute_import, division, print_function) + +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, 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, + TimeSeriesResults, TrajectoryResultValueAnnotations, TrajectoryResultValues, + TransectResultValueAnnotations, TransectResultValues, Units, VariableExtensionPropertyValues, + VariableExternalIdentifiers, Variables, +) -from sqlalchemy import func import pandas as pd -from odm2api.ODM2 import serviceBase -from odm2api.ODM2.models import * +from sqlalchemy import distinct, exists + +__author__ = 'sreeder' class DetailedResult: - def __init__(self, result, - samplingFeature, + def __init__(self, action, result, + sc, sn, method, variable, processingLevel, unit): # result.result_id etc. - self.resultID = result.ResultID - self.samplingFeatureCode = samplingFeature.SamplingFeatureCode - self.methodCode = method.MethodCode - self.variableCode = variable.VariableCode - self.processingLevelCode = processingLevel.ProcessingLevelCode - self.unitsName = unit.UnitsName - - self.samplingFeatureName = samplingFeature.SamplingFeatureName - self.methodName = method.MethodName - self.variableNameCV = variable.VariableNameCV - self.processingLevelDef = processingLevel.Definition + 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 - - #def __repr__(self): - # return str(self.name) + " " + str(self.organization) - -class ReadODM2( serviceBase ): - ''' - def __init__(self, session): - self._session = session - ''' - -# ################################################################################ -# Annotations -# ################################################################################ - - + self.AffiliationID = affiliation.AffiliationID + self.Name = person.PersonFirstName + ' ' + person.PersonLastName + self.Organization = '(' + org.OrganizationCode + ') ' + org.OrganizationName -# ################################################################################ -# CV -# ################################################################################ - - def getCVOrganizationTypes(self): - return self._session.query(CVOrganizationType).all() - - def getCVSamplingFeatureTypes(self): - """Select all on Sampling Features - - :return CVSamplingFeatureType Objects: - :type list: +class ReadODM2(serviceBase): + # Exists functions + def resultExists(self, result): """ - return self._session.query(CVSamplingFeatureType).all() - - def getCVSiteTypes(self): - """Select all on Sampling Features + Check to see if a Result Object exists + * Pass Result Object - return a boolean value of wether the given object exists - :return CVSiteType Objects: - :type list: """ - return self._session.query(CVSiteType).all() - - def getCVSpacialReferenceTypes(self): - """Select all on SpatialReferences - - :return CVSpacialReferenceType Objects: - :type list: - """ - return self._session.query(SpatialReferences).all() - - def getCVSamplingFeatureGeoTypes(self): - """Select all on Sampling Features - - :return CVSamplingFeatureGeoType Objects: - :type list: - """ - return self._session.query(CVSamplingFeatureGeoType).all() + try: - def getCVElevationDatums(self): - """Select all on CVElevationDatum + 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() - :return CVElevationDatum Objects: - :type list: - """ - return self._session.query(CVElevationDatum).all() - - def getCVVariableTypes(self): - """Select all on CVVariableType + except: + return None - :return CVVariableType Objects: - :type list: - """ - return self._session.query(CVVariableType).all() - - def getCVVariableNames(self): - """Select all on CVVariableName + # Annotations + def getAnnotations(self, type=None, codes=None, ids=None): + """ + * 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 + if type: + if type == 'action': + a = ActionAnnotations + elif type == 'categoricalresultvalue': + a = CategoricalResultValueAnnotations + elif type == 'equipmentannotation': + a = EquipmentAnnotations + elif type == 'measurementresultvalue': + a = MeasurementResultValueAnnotations + elif type == 'method': + a = MethodAnnotations + elif type == 'pointcoverageresultvalue': + a = PointCoverageResultValueAnnotations + elif type == 'profileresultvalue': + a = ProfileResultValueAnnotations + elif type == 'result': + a = ResultAnnotations + elif type == 'samplingfeature': + a = SamplingFeatureAnnotations + elif type == 'sectionresultvalue': + a = SectionResultValueAnnotations + elif type == 'spectraresultvalue': + a = SpectraResultValueAnnotations + elif type == 'timeseriesresultvalue': + a = TimeSeriesResultValueAnnotations + elif type == 'trajectoryresultvalue': + a = TrajectoryResultValueAnnotations + elif type == '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() - :return CVVariableName Objects: - :type list: - """ - return self._session.query(CVVariableName).all() - - def getCVSpeciations(self): - """Select all on CVSpeciation + except: + return None - :return CVSpeciation Objects: - :type list: - """ - return self._session.query(CVSpeciation).all() - - def getCVUnitsTypes(self): - """Select all on CVUnitsType + # CV + def getCVs(self, type): + """ + getCVs(self, type): + * Pass CVType - return a list of all objects of the given type + + """ + CV = CVActionType + if type == 'actiontype': + CV = CVActionType + elif type == 'aggregationstatistic': + CV = CVAggregationStatistic + elif type == 'annotationtype': + CV = CVAnnotationType + elif type == 'censorcode': + CV = CVCensorCode + elif type == 'dataqualitytype': + CV = CVDataQualityType + elif type == 'dataset type': + CV = CVDataSetType + elif type == 'Directive Type': + CV = CVDirectiveType + elif type == 'Elevation Datum': + CV = CVElevationDatum + elif type == 'Equipment Type': + CV = CVEquipmentType + elif type == 'Medium': + CV = CVMediumType + elif type == 'Method Type': + CV = CVMethodType + elif type == 'Organization Type': + CV = CVOrganizationType + elif type == 'Property Data Type': + CV = CVPropertyDataType + elif type == 'Quality Code': + CV = CVQualityCode + elif type == 'Relationship Type': + CV = CVRelationshipType + elif type == 'Result Type': + CV = CVResultType + elif type == 'Sampling Feature Geo-type': + CV = CVSamplingFeatureGeoType + elif type == 'Sampling Feature Type': + CV = CVSamplingFeatureType + elif type == 'Site Type': + CV = CVSiteType + elif type == 'Spatial Offset Type': + CV = CVSpatialOffsetType + elif type == 'Speciation': + CV = CVSpeciation + elif type == 'Specimen Type': + CV = CVSpecimenType + elif type == 'Status': + CV = CVStatus + elif type == 'Taxonomic Classifier Type': + CV = CVTaxonomicClassifierType + elif type == 'Units Type': + CV = CVUnitsType + elif type == 'Variable Name': + CV = CVVariableName + elif type == 'Variable Type': + CV = CVVariableType + else: + return None + try: + return self._session.query(CV).all() + except Exception as e: + print('Error running Query: {}'.format(e)) - :return CVUnitsType Objects: - :type list: + # Core + def getDetailedAffiliationInfo(self): """ - return self._session.query(CVUnitsType).all() + * Pass Nothing - Return a list of all Affiliations with detailed information, + including Affiliation, People and Organization - def getCVActionTypes(self): - """ - Select all on CVActionType - """ - return self._session.query(CVActionType).all() - - def getCVMethodTypes(self): - """ - Select all on CVMethodType - """ - return self._session.query(CVMethodType).all() - - def getCVMediumTypes(self): - """ - Select all on CVMediumType - """ - return self._session.query(CVMediumType).all() - - def getCVAggregationStatistics(self): """ - Select all on CVAggregationStatistic - """ - return self._session.query(CVAggregationStatistic).all() - - def getCVStatus(self): - """ - Select all on CVStatus - """ - return self._session.query(CVStatus).all() - -# ################################################################################ -# Core -# ################################################################################ - - def getDetailedAffiliationInfo(self): - q = self._session.query(Affiliations, People, Organizations)\ - .filter(Affiliations.PersonID==People.PersonID)\ - .filter(Affiliations.OrganizationID==Organizations.OrganizationID) + 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) + for a, p, o in q.all(): + detailedAffiliation = DetailedAffiliation(a, p, o) affiliationList.append(detailedAffiliation) return affiliationList - def getDetailedResultInfo(self, resultTypeCV, resultID=None): - q = self._session.query(Results, SamplingFeatures, 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) + 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: - for r,s,m,v,p,u in q.filter_by(ResultID=resultID).all(): - detailedResult = DetailedResult(\ - r,s,m,v,p,u) - resultList.append(detailedResult) - else: - for r,s,m,v,p,u in q.all(): - detailedResult = DetailedResult(\ - r,s,m,v,p,u) - resultList.append(detailedResult) - return resultList + q = q.filter(Results.ResultID == resultID) - """ - Taxonomic Classifiers - """ + 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): - return self._session.query(TaxonomicClassifiers).all() - - - """ - Variable - """ - - def getVariables(self): - """Select all on Variables - - :return Variable Objects: - :type list: """ - return self._session.query(Variables).all() + getTaxonomicClassifiers(self): + * Pass nothing - return a list of all objects - def getVariableById(self, variableId): - """Select by variableId - - :param variableId: - :type Integer: - :return Return matching Variable object filtered by variableId: - :type Variable: """ - try: - return self._session.query(Variables).filter_by(VariableID=variableId).first() - except: - return None - - def getVariableByCode(self, variableCode): - """Select by variableCode + return self._session.query(TaxonomicClassifiers).all() - :param variableCode: - :type String: - :return Return matching Variable Object filtered by variableCode: - :type Variable: - """ + # 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: + 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: + 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 self._session.query(Variables).filter_by(VariableCode=variableCode).first() - except: + return query.all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - def getResultById(self, resultId): - """Select by variableId - - :param variableId: - :type Integer: - :return Return matching Variable object filtered by variableId: - :type Variable: + # Method + def getMethods(self, ids=None, codes=None, type=None): """ - try: - return self._session.query(Results).filter_by(ResultID=resultId).first() - except: - return None - """ - Method - """ - - def getMethods(self): - """Select all on Methods + * 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 - :return Method Objects: - :type list: """ - return self._session.query(Methods).all() + q = self._session.query(Methods) + if ids: + q = q.filter(Methods.MethodID.in_(ids)) + if codes: + q = q.filter(Methods.MethodCode.in_(codes)) + if type: + q = q.filter_by(MethodTypeCV=type) - def getMethodById(self, methodId): - """Select by methodId - - :param methodId: - :type Integer - :return Return matching Method Object filtered by methodId: - :type Method: - """ try: - return self._session.query(Methods).filter_by(MethodID=methodId).first() - except: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - def getMethodByCode(self, methodCode): - """Select by methodCode - - :param methodCode: - :type String: - :return Return matching Method Object filtered by method Code: - :type Method: + # ProcessingLevel + def getProcessingLevels(self, ids=None, codes=None): """ - try: - return self._session.query(Methods).filter_by(MethodCode=methodCode).first() - except: - return None - - def getMethodsByType(self, methodTypeCV): - return self._session.query(Methods).filter_by(MethodTypeCV=methodTypeCV).all() - - """ - ProcessingLevel - """ + getProcessingLevels(self, ids=None, codes=None) + * Pass nothing - returns full list of ProcessingLevel objects + * Pass a list of ProcessingLevelID - returns a single processingLevel object for each given id + * Pass a list of ProcessingLevelCode - returns a single processingLevel object for each given code - def getProcessingLevels(self): - """Select all on Processing Level - - :return ProcessingLevel Objects: - :type list: """ - return self._session.query(ProcessingLevels).all() - - def getProcessingLevelById(self, processingId): - """Select by processingId + q = self._session.query(ProcessingLevels) + if ids: + q = q.filter(ProcessingLevels.ProcessingLevelsID.in_(ids)) + if codes: + q = q.filter(ProcessingLevels.ProcessingLevelCode.in_(codes)) - :param processingId: - :type Integer: - :return Return matching ProcessingLevel Object filtered by processingId: - :type Processinglevel: - """ try: - return self._session.query(ProcessingLevels).filter_by(ProcessingLevelID=processingId).first() - except: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - def getProcessingLevelByCode(self, processingCode): - """Select by processingCode - - :param processingCode: - :type String(50): - :return Return matching Processinglevel Object filtered by processingCode: - :type Processinglevel: - """ + # Sampling Feature + def getSamplingFeatures(self, ids=None, codes=None, uuids=None, type=None, wkt=None, results=False): + """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. + type (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) + + """ + if results: + try: + fas = [x[0] for x in self._session.query(distinct(Results.FeatureActionID)).all()] + except: + return None + sf = [x[0] for x in self._session.query(distinct(FeatureActions.SamplingFeatureID)) + .filter(FeatureActions.FeatureActionID.in_(fas)).all()] + if ids: + ids = list(set(ids).intersection(sf)) + else: + ids = sf + + q = self._session.query(SamplingFeatures) + + if type: + q = q.filter_by(SamplingFeatureTypeCV=type) + 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 self._session.query(ProcessingLevels).filter_by(ProcessingLevelCode=str(processingCode)).first() + return q.all() except Exception as e: - print(e) + print('Error running Query: {}'.format(e)) return None - """ - Sampling Feature - """ - - def getSamplingFeatures(self): - """Select all on SamplingFeatures - - :return SamplingFeature Objects: - :type list: + 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 - return self._session.query(SamplingFeatures).all() + """ - def getSamplingFeatureById(self, samplingId): - """Select by samplingId + sf = self._session.query(distinct(SamplingFeatures.SamplingFeatureID))\ + .select_from(RelatedFeatures) - :param samplingId: - :type Integer: - :return Return matching SamplingFeature Object filtered by samplingId: - :type SamplingFeature: - """ + 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: - return self._session.query(SamplingFeatures).filter_by(SamplingFeatureID=samplingId).first() - except: - return None + sfids = [x[0] for x in sf.all()] + if len(sfids) > 0: + sflist = self.getSamplingFeatures(ids=sfids) + return sflist - def getSamplingFeatureByCode(self, samplingFeatureCode): - """Select by samplingFeatureCode + except Exception as e: + print('Error running Query: {}'.format(e)) + return None + + # Action + def getActions(self, ids=None, type=None, sfid=None): + """ + * 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 - :param samplingFeatureCode: - :type String: - :return Return matching SamplingFeature Object filtered by samplingId - :type list: """ + a = Actions + if type == 'equipment': + a = EquipmentActions + elif type == 'calibration': + a = CalibrationActions + elif type == '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 self._session.query(SamplingFeatures).filter_by(SamplingFeatureCode=samplingFeatureCode).first() + return q.all() except Exception as e: + print('Error running Query: {}'.format(e)) return None - def getSamplingFeaturesByType(self, samplingFeatureTypeCV): - """Select by samplingFeatureTypeCV + def getRelatedActions(self, actionid=None): + """ + * Pass an ActionID - get a list of Action objects related to the input + action along with the relationship type - :param samplingFeatureTypeCV: - :type String: - :return Return matching SamplingFeature Objects filtered by samplingFeatureTypeCV: - :type list: """ + q = self._session.query(Actions).select_from(RelatedActions).join(RelatedActions.RelatedActionObj) + if actionid: + q = q.filter(RelatedActions.ActionID == actionid) try: - return self._session.query(SamplingFeatures).filter_by(SamplingFeatureTypeCV=samplingFeatureTypeCV).all() + return q.all() except Exception as e: - print(e) + print('Error running Query: {}'.format(e)) return None - def getSamplingFeatureByGeometry(self, wkt_geometry): + # Unit + def getUnits(self, ids=None, name=None, type=None): + """ + * 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 + """ + q = self._session.query(Units) + if ids: + q = q.filter(Units.UnitsID.in_(ids)) + if name: + q = q.filter(Units.UnitsName.ilike(name)) + if type: + q = q.filter(Units.UnitsTypeCV.ilike(type)) try: - # ST_Equals(geometry, geometry) - return self._session.query(SamplingFeatures).filter( - func.ST_AsText(SamplingFeatures.FeatureGeometry) == func.ST_AsText(wkt_geometry)).first() + return q.all() except Exception as e: - print(e) + print('Error running Query: {}'.format(e)) return None - def getGeometryTest(self, TestGeom): - Geom = self._session.query(SamplingFeatures).first() - print("Queried Geometry: ", self._session.query(Geom.FeatureGeometry.ST_AsText()).first()) - GeomText = self._session.query( - func.ST_Union(Geom.FeatureGeometry, func.ST_GeomFromText(TestGeom)).ST_AsText()).first() - print(GeomText) - - """ - Action - """ - - def getActions(self): - """ - Select all on Action + # Organization + def getOrganizations(self, ids=None, codes=None): """ - return self._session.query(Actions).all() + * 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 - def getActionById(self, actionId): - """ - Select by actionId """ + 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 self._session.query(Actions).filter_by(ActionID=actionId).first() - except: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - - - """ - Unit - """ - - def getUnits(self): - """Select all on Unit - :return Unit Objects: - :type list: + # Person + def getPeople(self, ids=None, firstname=None, lastname=None): """ - return self._session.query(Units).all() - - def getUnitById(self, unitId): - """Select by samplingId + * 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 - :param unitId: - :type Integer: - :return Return matching Unit Object filtered by UnitId: - :type Unit: """ + 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 self._session.query(Units).filter_by(UnitsID=unitId).first() - except: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - def getUnitByName(self, unitName): + 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. - try: - return self._session.query(Units).filter(Units.UnitsName.ilike(unitName)).first() - except: - return None - - def getUnitsByTypeCV(self, unitsTypeCV): - try: - return self._session.query(Units).filter(Units.UnitsTypeCV.ilike(unitsTypeCV)).all() - except: - return None + Args: + ids (list, optional): List of AffiliationIDs. + personfirst (str, optional): Person First Name. + personlast (str, optional): Person Last Name. + orgcode (str, optional): Organization Code. - """ - Organization - """ + Returns: + list: List of Affiliation objects - def getOrganizations(self): - """Select all on Organization + Examples: + >>> ReadODM2.getAffiliations(ids=[39,40]) + >>> ReadODM2.getAffiliations(personfirst='John', + ... personlast='Smith') + >>> ReadODM2.getAffiliations(orgcode='Acme') - :return Organization Objects: - :type list: """ - return self._session.query(Organizations).all() + q = self._session.query(Affiliations) - def getOrganizationById(self, orgId): - """Select by orgId + 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)) - :param orgId: - :type Integer: - :return Return matching Unit Object filtered by orgId: - :type Organization: - """ try: - return self._session.query(Organizations).filter_by(OrganizationID=orgId).first() - except: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - def getOrganizationByCode(self, orgCode): - """Select by orgCode + # Results + def getResults(self, ids=None, type=None, uuids=None, actionid=None, simulationid=None, sfid=None, + variableid=None, siteid=None): + + # 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. + type (str, optional): Type of Result from + `controlled vocabulary name `_. + uuids (list, optional): List of UUIDs string. + actionid (int, optional): ActionID. + simulationid (int, optional): SimulationID. + sfid (int, optional): SamplingFeatureID. + variableid (int, optional): VariableID. + siteid (int, optional): SiteID. + + Returns: + list: List of Result objects + + Examples: + >>> ReadODM2.getResults(ids=[39,40]) + >>> ReadODM2.getResults(type='Time series coverage') + >>> ReadODM2.getResults(sfid=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) + + if type: + query = query.filter_by(ResultTypeCV=type) + 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: + query = query.join(FeatureActions).filter_by(SamplingFeatureID=sfid) + + 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() + ] + query = query.join(FeatureActions).filter(FeatureActions.SamplingFeatureID.in_(sfids)) - :param orgCode: - :type String: - :return Return matching Organization Object filtered by orgCode - :type Organization: - """ try: - return self._session.query(Organizations).filter_by(OrganizationCode=orgCode).first() - - except: + return query.all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - """ - Person - """ - - def getPeople(self): - """Select all on Person - - :return Person Objects: - :type list: + # Datasets + def getDataSets(self, codes=None, uuids=None): """ - return self._session.query(People).all() - - def getPersonById(self, personId): - """Select by personId - - :param personId: - :type Integer: - :return Return matching Person Object filtered by personId: - :type Person: + * Pass nothing - returns a list of all DataSet objects + * Pass a list of DataSetCode - returns a single DataSet object for each code + * Pass a list of UUIDS - returns a single DataSet object for each UUID """ + q = self._session.query(DataSets) + if codes: + q = q.filter(DataSets.DataSetCode.in_(codes)) + if uuids: + q.q.filter(DataSets.DataSetUUID.in_(uuids)) try: - return self._session.query(People).filter_by(PersonID=personId).first() - - except: + return q.all() + except Exception as e: + print('Error running Query {}'.format(e)) return None - def getPersonByName(self, personfirst, personlast): - """Select by person name, last name combination - - :param personfirst: first name of person - :param personlast: last name of person - :return Return matching Person Object: - :type Person: + # Data Quality + def getDataQuality(self): """ - try: - return self._session.query(People).filter(People.PersonFirstName.ilike(personfirst)). \ - filter(People.PersonLastName.ilike(personlast)).first() - except: - return None - - def getAllAffiliations(self): - try: - return self._session.query(Affiliations).all() - except: - return None + * Pass nothing - return a list of all objects + """ + return self._session.query(DataQuality).all() - def getAffiliationByPersonAndOrg(self, personfirst, personlast, orgcode): + # TODO DataQuality Schema Queries + def getReferenceMaterials(self): """ - Select all affiliation of person - :param personfirst: first name of person - :param personlast: last name of person - :param orgcode: organization code (e.g. uwrl) - :return: ODM2.Affiliation + * Pass nothing - return a list of all objects """ + return self._session.query(ReferenceMaterials).all() - try: - return self._session.query(Affiliations).filter(Organizations.OrganizationCode.ilike(orgcode)) \ - .filter(People.PersonFirstName.ilike(personfirst)) \ - .filter(People.PersonLastName.ilike(personlast)).first() - except: - return None - - def getAffiliations(self): - return self._session.query(Affiliations).all() - - def getAffiliationsByPerson(self, personfirst, personlast): + def getReferenceMaterialValues(self): """ - Select all affiliation of person - :param personfirst: first name of person - :param personlast: last name of person - :return: [ODM2.Affiliation] + * Pass nothing - return a list of all objects """ + return self._session.query(ReferenceMaterialValues).all() - try: - return self._session.query(Affiliations).filter(People.PersonFirstName.ilike(personfirst)) \ - .filter(People.PersonLastName.ilike(personlast)).all() - except: - return None - - """ - Results - """ - - def getResults(self): - - try: - return self._session.query(Results).all() - except: - return None - - def getResultByActionID(self, actionID): - - try: - return self._session.query(Results).join(FeatureActions).join(Actions).filter_by(ActionID=actionID).all() - except: - return None - - def getResultByID(self, resultID): - try: - return self._session.query(Results).filter_by(ResultID=resultID).one() - except: - return None - - def getResultAndGeomByID(self, resultID): - try: - return self._session.query(Results, SamplingFeatures.FeatureGeometry.ST_AsText()). \ - join(FeatureActions). \ - join(SamplingFeatures). \ - join(Results). \ - filter_by(ResultID=resultID).one() - except: - return None - - def getResultAndGeomByActionID(self, actionID): - - try: - return self._session.query(Results, SamplingFeatures.FeatureGeometry.ST_AsText()). \ - join(FeatureActions). \ - join(SamplingFeatures). \ - join(Actions). \ - filter_by(ActionID=actionID).all() - except: - return None - - def getResultValidDateTime(self, resultId): - q = self._session.query(Results.ValidDateTime).filter(Results.ResultID==int(resultId)) - return q.first() - - """ - Datasets - """ - - def getDataSets(self): - try: - return self._session.query(DataSets).all() - except: - return None - - def getDatasetByCode(self, dscode): - - try: - return self._session.query(DataSets).filer(DataSets.DataSetCode.ilike(dscode)).first() - except: - return None - - -# ################################################################################ -# Data Quality -# ################################################################################ - - - def getAllDataQuality(self): - """Select all on Data Quality - - :return Dataquality Objects: - :type list: + def getResultNormalizationValues(self): """ - return self._session.query(DataQuality).all() - - -# ################################################################################ -# Equipment -# ################################################################################ - - - def getAllEquipment(self): - return self._session.query(Equipment).all() - - -# ################################################################################ -# Extension Properties -# ################################################################################ - - - -# ################################################################################ -# External Identifiers -# ################################################################################ - - - - -# ################################################################################ -# Lab Analyses -# ################################################################################ - - - + * Pass nothing - return a list of all objects + """ + return self._session.query(ResultNormalizationValues).all() -# ################################################################################ -# Provenance -# ################################################################################ + 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, type=None, sfid=None, actionid=None): + """ + * 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 - """ - Citation - """ + """ + 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 getCitations(self): - self._session.query(Citations).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 -# ################################################################################ -# Results -# ################################################################################ + """ + return self._session.query(DataLoggerFileColumns).all() + def DataLoggerFiles(self): + """ + * Pass nothing - return a list of all objects - """ - TimeSeriesResults - """ + """ + return self._session.query(DataLoggerFiles).all() - def getTimeSeriesResults(self): - """Select all on TimeSeriesResults + def DataloggerProgramFiles(self): + """ + * Pass Nothing - return a list of all objects - :return TimeSeriesResults Objects: - :type list: """ - return self._session.query(TimeSeriesResults).all() + return self._session.query(DataLoggerProgramFiles).all() - def getTimeSeriesResultByResultId(self, resultId): - """Select by resultID on ResultID + def EquipmentModels(self): + """ + * Pass Nothing - return a list of all objects - :param resultId: - :type Integer: - :return return matching Timeseriesresult Object filtered by resultId """ + return self._session.query(EquipmentModels).all() - try: - return self._session.query(TimeSeriesResults).filter_by(ResultID=resultId).one() - except: - return None + def EquipmentUsed(self): + """ + * Pass Nothing - return a list of all objects - def getTimeSeriesResultbyCode(self, timeSeriesCode): - """Select by time """ - pass + return self._session.query(EquipmentUsed).all() - """ - TimeSeriesResultValues - """ + def InstrumentOutputVariables(self, modelid=None, variableid=None): + """ + * Pass Nothing - return a list of all objects + * Pass ModelID + * Pass VariableID - def getTimeSeriesResultValues(self): - """Select all on TimeSeriesResults + """ + i = self._session.query(InstrumentOutputVariables) + if modelid: + i = i.filter_by(ModelID=modelid) + if variableid: + i = i.filter_by(VariableID=variableid) + return i.all() - :return TimeSeriesResultsValue Objects: - :type list: + def RelatedEquipment(self, code=None): """ + * Pass nothing - return a list of all objects + * Pass code- return a single object with the given code - q = self._session.query(TimeSeriesResults).all() - df = pd.DataFrame([dv.list_repr() for dv in q]) - df.columns = q[0].get_columns() - return df - # return self._session.query(Timeseriesresultvalue).all() + """ + r = self._session.query(RelatedEquipment) + if code: + r = r.filter_by(EquipmentCode=code) + return r.all() - def getTimeSeriesResultValuesByResultId(self, resultId): - """Select by resultId + # Extension Properties + def getExtensionProperties(self, type=None): + """ + * Pass nothing - return a list of all objects + * Pass type- return a list of all objects of the given type - :param timeSeriesId: - :type Integer: - :return return matching Timeseriesresultvalue Object filtered by resultId: - :type Timeseriesresultvalue: """ + # Todo what values to use for extensionproperties type + e = ExtensionProperties + if type == 'action': + e = ActionExtensionPropertyValues + elif type == 'citation': + e = CitationExtensionPropertyValues + elif type == 'method': + e = MethodExtensionPropertyValues + elif type == 'result': + e = ResultExtensionPropertyValues + elif type == 'samplingfeature': + e = SamplingFeatureExtensionPropertyValues + elif type == 'variable': + e = VariableExtensionPropertyValues try: - q = self._session.query(TimeSeriesResultValues).filter_by(ResultID=resultId).all() - print(type(q[0]), q[0]) - df = pd.DataFrame([dv.list_repr() for dv in q]) - df.columns = q[0].get_columns() - return df - # return self._session.query(Timeseriesresultvalue).filter_by(ResultID=resultId).all() + return self._session.query(e).all() except Exception as e: - print(e) + print('Error running Query: {}'.format(e)) return None - def getTimeSeriesResultValuesByCode(self, timeSeriesCode): - """ - - :param timeSeriesCode: - :return: - """ - pass - - def getTimeSeriesResultValuesByTime(self, resultid, starttime, endtime=None): - - # set end = start if it is None - endtime = starttime if not endtime else endtime - + # External Identifiers + def getExternalIdentifiers(self, type=None): + """ + * Pass nothing - return a list of all objects + * Pass type- return a list of all objects of the given type + + """ + e = ExternalIdentifierSystems + if type.lowercase == 'citation': + e = CitationExternalIdentifiers + elif type == 'method': + e = MethodExternalIdentifiers + elif type == 'person': + e = PersonExternalIdentifiers + elif type == 'referencematerial': + e = ReferenceMaterialExternalIdentifiers + elif type == 'samplingfeature': + e = SamplingFeatureExternalIdentifiers + elif type == 'spatialreference': + e = SpatialReferenceExternalIdentifiers + elif type == 'taxonomicclassifier': + e = TaxonomicClassifierExternalIdentifiers + elif type == 'variable': + e = VariableExternalIdentifiers try: - return self._session.query(TimeSeriesResultValues).filter_by(ResultID=resultid) \ - .filter(TimeSeriesResultValues.ValueDateTime >= starttime) \ - .filter(TimeSeriesResultValues.ValueDateTime <= endtime) \ - .order_by(TimeSeriesResultValues.ValueDateTime).all() - except: + return self._session.query(e).all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - -# ################################################################################ -# Annotations -# ################################################################################ - - - """ - Site - """ - - def getAllSites(self): - """Select all on Sites - - :return Site Objects: - :type list: + # TODO functions for Lab Analyses + # Lab Analyses + def getDirectives(self): """ - return self._session.query(Sites).all() - - def getSiteBySFId(self, siteId): - """Select by siteId + getDirectives(self) + * Pass nothing - return a list of all objects - :param siteId: - :type Integer: - :return Return matching Site Object filtered by siteId: - :type Site: """ - try: - return self._session.query(Sites).filter_by(SamplingFeatureID=siteId).one() - except: - return None + return self._session.query(Directives).all() + def getActionDirectives(self): + """ + getActionDirectives(self) + * Pass nothing - return a list of all objects - def getSiteBySFCode(self, siteCode): - """Select by siteCode + """ + return self._session.query(ActionDirectives).all() - :param siteCode: - :type String: - :return Return matching Samplingfeature Object filtered by siteCode: - :type Samplingfeature: + def getSpecimenBatchPositions(self): """ + getSpecimenBatchPositions(self) + * Pass nothing - return a list of all objects - sf = self._session.query(SamplingFeatures).filter_by(SamplingFeatureCode=siteCode).one() - return self._session.query(Sites).filter_by(SamplingFeatureID=sf.SamplingFeatureID).one() + """ + return self._session.query(SpecimenBatchPositions).all() - def getSpatialReferenceByCode(self, srsCode): + # TODO functions for Provenance + # Provenance + def getAuthorLists(self): + """ + getAuthorLists(self) + * Pass nothing - return a list of all objects + """ + return self._session.query(AuthorLists).all() - try: - return self._session.query(SpatialReferences).filter(SpatialReferences.SRSCode.ilike(srsCode)).first() - except: - return None + def getDatasetCitations(self): + """ + getDatasetCitations(self) + * Pass nothing - return a list of all objects + """ + return self._session.query(DataSetCitations).all() -# ################################################################################ -# Sensors -# ################################################################################ + 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 getAllDeploymentAction(self): - """Select all on DeploymentAction + def getRelatedAnnotations(self): + """ + getRelatedAnnotations(self) + * Pass nothing - return a list of all objects - :return DeploymentAction Objects: - :type list: """ - return self._session.query(DeploymentAction).all() + return self._session.query(RelatedAnnotations).all() - # return self._session.query) + def getRelatedCitations(self): + """ + getRelatedCitations(self) + * Pass nothing - return a list of all objects - def getDeploymentActionById(self, deploymentId): - """Select by deploymentId + """ + return self._session.query(RelatedCitations).all() - :param deploymentId: - :type Integer: - :return Return Matching DeploymentAction Object filtered by deploymentId: - :type DeploymentAction: + def getRelatedDatasets(self): """ - try: - return self._session.query(DeploymentAction).filter_by(DeploymentActionID=deploymentId).one() - except: - return None + getRelatedDatasets(self) + * Pass nothing - return a list of all objects - def getDeploymentActionByCode(self, deploymentCode): - """Select by deploymentCode + """ + return self._session.query(RelatedDataSets).all() - :param deploymentCode: - :type String: - :return Return matching DeploymentAction Object filtered by deploymentCode: - :type DeploymentAction: + def getRelatedResults(self): """ - try: - return self._session.query(Deploymentaction).filter_by(DeploymentActionCode=deploymentCode).one() - except: - return None + getRelatedResults(self) + * Pass nothing - return a list of all objects + """ + return self._session.query(RelatedResults).all() -# ################################################################################ -# Simulation -# ################################################################################ + def getResultDerivationEquations(self): + """ + getResultDerivationEquations(self) + * Pass nothing - return a list of all objects + """ + return self._session.query(ResultDerivationEquations).all() - def getAllModels(self): + # Results + # ResultValues + def getResultValues(self, resultids, starttime=None, endtime=None): + """ + getResultValues(self, resultids, starttime=None, endtime=None) + * Pass in a list of ResultID - Returns a pandas dataframe object of type + that is specific to the result type - The resultids must be associated + with the same value type + * Pass a ResultID and a date range - returns a pandas dataframe object + of type that is specific to the result type with values between the input date range + * Pass a starttime - Returns a dataframe with the values after the given start time + * Pass an endtime - Returns a dataframe with the values before the given end time - try: - return self._session.query(Models).all() - except: - return None + """ + type = self._session.query(Results).filter_by(ResultID=resultids[0]).first().ResultTypeCV + ResultType = TimeSeriesResults + if 'categorical' in type.lower(): + ResultType = CategoricalResultValues + elif 'measurement' in type.lower(): + ResultType = MeasurementResultValues + elif 'point' in type.lower(): + ResultType = PointCoverageResultValues + elif 'profile' in type.lower(): + ResultType = ProfileResultValues + elif 'section' in type.lower(): + ResultType = SectionResults + elif 'spectra' in type.lower(): + ResultType = SpectraResultValues + elif 'time' in type.lower(): + ResultType = TimeSeriesResultValues + elif 'trajectory' in type.lower(): + ResultType = TrajectoryResultValues + elif 'transect' in type.lower(): + ResultType = TransectResultValues - def getModelByCode(self, modelcode): + q = self._session.query(ResultType).filter(ResultType.ResultID.in_(resultids)) + if starttime: + q = q.filter(ResultType.ValueDateTime >= starttime) + if endtime: + q = q.filter(ResultType.ValueDateTime <= endtime) try: - return self._session.query(Models).filter(Models.ModelCode.ilike(modelcode)).first() - except: + # 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 + ) + return df + except Exception as e: + print('Error running Query: {}'.format(e)) return None - def getAllSimulations(self): + # 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 self._session.query(Simulations).all() - except: + return q.all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - def getSimulationByName(self, simulationName): - try: - return self._session.query(Simulations).filter(Simulations.SimulationName.ilike(simulationName)).first() - except: - 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 - def getSimulationByActionID(self, actionID): + """ + s = self._session.query(Simulations) + if name: + s = s.filter(Simulations.SimulationName.ilike(name)) + if actionid: + s = s.filter_by(ActionID=actionid) try: - return self._session.query(Simulations).filter_by(ActionID=actionID).first() - except: + return s.all() + except Exception as e: + print('Error running Query: {}'.format(e)) return None - def getRelatedModelsByID(self, modelid): + def getModels(self, codes=None): """ - queries the ODM2 for any models that have a relationship with the provided model id - :param modelid: id of the model to search - :return: all models related to the specified id + 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 self._session.query(RelatedModels).filter_by(RelatedModelID=modelid).all() + return m.all() except Exception as e: - print(e) - return None + print('Error running Query: {}'.format(e)) + return None - def getRelatedModelsByCode(self, modelcode): + def getRelatedModels(self, id=None, code=None): """ - queries the ODM2 for any models that have a relationship with the provided model id - :param modelcode: the code of the model to search - :return: all models related to the provided model code + 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 + """ - try: - return self._session.query(RelatedModels).join(Models, RelatedModels.RelatedModelID == Models.ModelID) \ - .filter(Models.ModelCode == modelcode).all() - except Exception as e: - print(e) - return None + m = self._session.query(Models).select_from(RelatedModels).join(RelatedModels.ModelObj) + if id: + m = m.filter(RelatedModels.ModelID == id) + if code: + m = m.filter(Models.ModelCode == code) - def getResultsBySimulationID(self, simulationID): try: - return self._session.query(Results) \ - .join(FeatureActions) \ - .join(Actions) \ - .join(Simulations) \ - .filter(Simulations.SimulationID == simulationID).all() + return m.all() except Exception as e: - print(e) - return None - -# ################################################################################ -# ODM2 -# ################################################################################ - -class readODM2(object): - def test(self): - return None + print('Error running Query: {}'.format(e)) + return None diff --git a/odm2api/ODM2/services/updateService.py b/odm2api/ODM2/services/updateService.py index 0f071d7..1bec3ce 100644 --- a/odm2api/ODM2/services/updateService.py +++ b/odm2api/ODM2/services/updateService.py @@ -1,3 +1,5 @@ +from __future__ import (absolute_import, division, print_function) + __author__ = 'jmeline' from datetime import datetime @@ -11,22 +13,52 @@ # ################################################################################ class UpdateODM2(serviceBase): - def test(self): - return None + def update(self, value): + self._session.add(value) + self._session.commit() + return value # ################################################################################ -# CV +# 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)).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() - -# ################################################################################ -# Core -# ################################################################################ - def updateResultValidDateTime(self, resultId, dateTime): - q = self._session.query(Results).filter(Results.ResultID==int(resultId)).update({'ValidDateTime':dateTime.to_datetime()}) + 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() @@ -96,4 +128,3 @@ def updateResultValidDateTime(self, resultId, dateTime): # ################################################################################ # ODM2 # ################################################################################ - diff --git a/odm2api/ODMconnection.py b/odm2api/ODMconnection.py index 410f97b..c3c1833 100644 --- a/odm2api/ODMconnection.py +++ b/odm2api/ODMconnection.py @@ -1,233 +1,160 @@ +from __future__ import (absolute_import, division, print_function) -from sqlalchemy.exc import SQLAlchemyError, DBAPIError -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker - -from .ODM2.models import Variables as Variable2, setSchema -#from .versionSwitcher import ODM, refreshDB #import Variable as Variable1 -from .ODM1_1_1.services import ODM#, refreshDB -import urllib -import sys import os +import sys +try: + from urllib import quote_plus +except ImportError: + from urllib.parse import quote_plus + +from odm2api.ODM2.models import setSchema +from sqlalchemy import create_engine +from sqlalchemy.orm import scoped_session, sessionmaker -# LIBSPATIALITE_PATH = './libspatialite.so.5.1.0' class SessionFactory(): - def __init__(self, connection_string, echo=True, version = 1.1): + def __init__(self, connection_string, echo=True, version=2.0): + if 'sqlite' in connection_string: - # from sqlite3 import dbapi2 as sqlite - # put the spatialite dll on the path. If one had pyspatialite installed thn - # this would not be required... but trying to get that on a windows machine - # was way too hard to bother - # dirDLLspatialite = 'C:/bin' - # os.environ['PATH'] = dirDLLspatialite + ';' + os.environ['PATH'] - - # #engine = create_engine('sqlite:///D:\\temp\\test_1.db', module=sqlite, echo=False) - # engine = create_engine(connection_string, module=sqlite, echo=False) - - # this enables the extension on each connection - # @event.listens_for(engine, "connect") - # def connect(dbapi_connection, connection_rec): - # dbapi_connection.enable_load_extension(True) - # dbapi_connection.execute("SELECT load_extension('libspatialite-4.dll')") - - #from pysqlite2 import dbapi2 as sqlite - #import pyspatialite.dpabi as sqlite - # self.engine = create_engine(connection_string, model = sqlite ,encoding='utf-8', echo=echo) - - # @event.listens_for(self.engine, "connect") - # def connect(dbapi_connection, connection_rec): - # dbapi_connection.enable_load_extension(True) - # dbapi_connection.execute("SELECT load_extension('{0}');".format("mod_spatialite")) - - # self.engine.execute("SELECT InitSpatialMetaData();")# - # self.engine.connect().connection.enable_load_extension(True) - # self.engine.execute("SELECT load_extension('mod_spatialite');")# - self.engine = create_engine(connection_string, encoding='utf-8', echo=echo) + self.engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=100) self.test_engine = self.engine - elif 'mssql' in connection_string: - import pyodbc - self.engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600) - self.test_engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, connect_args={'timeout': 1}) + self.engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=100) + self.test_engine = create_engine(connection_string, encoding='utf-8', + echo=echo, connect_args={'timeout': 1}) elif 'postgresql' in connection_string or 'mysql' in connection_string: - self.engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, pool_timeout=5, pool_size=20, max_overflow=0) - self.test_engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=3600, pool_timeout=5, max_overflow=0, connect_args={'connect_timeout': 1}) + self.engine = create_engine(connection_string, encoding='utf-8', echo=echo, pool_recycle=100) + self.test_engine = create_engine(connection_string, encoding='utf-8', echo=echo, + max_overflow=0, connect_args={'connect_timeout': 1}) - # Create session maker - self.Session = sessionmaker(bind=self.engine) - self.test_Session = sessionmaker(bind=self.test_engine) - self.version=version + # Create session maker. + self.Session = scoped_session(sessionmaker(bind=self.engine, autoflush=True)) + self.test_Session = scoped_session(sessionmaker(bind=self.test_engine)) + setSchema(self.engine) + self.version = version def getSession(self): return self.Session() def __repr__(self): - return "" % (self.engine) + return '' % self.engine class dbconnection(): def __init__(self, debug=False): self.debug = debug - self._connections = [] - self.version = 0 - self._connection_format = "%s+%s://%s:%s@%s/%s" - self._connection_format_nopassword = "%s+%s://%s@%s/%s" + self.version = -1 + self._connection_format = '%s+%s://%s:%s@%s/%s' + self._connection_format_nopassword = '%s+%s://%s@%s/%s' @classmethod - def createConnection(self, engine, address, db=None, user=None, password=None, dbtype = 2.0, echo=False): + def createConnection(self, engine, address, db=None, user=None, password=None, dbtype=2.0, echo=False): if engine == 'sqlite': - connection_string = engine +':///'+address - s = SessionFactory(connection_string, echo = echo, version= dbtype) - setSchema(s.engine) - return s - + connection_string = engine + ':///' + address + return self.createConnectionFromString(connection_string, dbtype, echo) else: - connection_string = dbconnection.buildConnDict(dbconnection(), engine, address, db, user, password) + connection_string = dbconnection.__buildConnectionString( + dbconnection(), engine, address, db, user, password + ) if self.isValidConnection(connection_string, dbtype): - s= SessionFactory(connection_string, echo = echo, version= dbtype) - setSchema(s.engine) - return s - else : + return self.createConnectionFromString(connection_string, dbtype, echo) + else: return None - # if self.testConnection(connection_string): @classmethod - def isValidConnection(self, connection_string, dbtype=2.0): - #refreshDB(dbtype) + def createConnectionFromString(self, conn_string, dbtype=2.0, echo=False): + s = SessionFactory(conn_string, echo=echo, version=dbtype) + return s + @classmethod + def isValidConnection(self, connection_string=None, dbtype=2.0): + # refreshDB(dbtype) if dbtype == 2.0: if self.testEngine(connection_string): - # print "sucess" - return True + return True else: return False else: if self.testEngine1_1(connection_string): - # print "sucess" return True else: return False @classmethod - def testEngine(self, connection_string, echo = False ): - s = SessionFactory(connection_string, echo=echo) + def testEngine(self, connection_string, echo=False): + s = SessionFactory(connection_string, echo=echo, version=2.0) try: setSchema(s.test_engine) - s.test_Session().query(Variable2.VariableCode).limit(1).first() - + # s.test_Session().query(Variable2.VariableCode).limit(1).first() + s.test_Session().execute('Select 1') except Exception as e: - print("Connection was unsuccessful ", e.message) + print('Connection was unsuccessful {}'.format(e.message)) return False + finally: + dbconnection.closeConnection(s.test_Session) return True @classmethod - def testEngine1_1(self, connection_string, echo = False ): - s = SessionFactory(connection_string, echo=echo) + def testEngine1_1(self, connection_string, echo=False): + s = SessionFactory(connection_string, echo=echo, version=1.1) try: - # s.ms_test_Session().query(Variable1).limit(1).first() - s.test_Session().query(ODM.Variable.code).limit(1).first() + # s.test_Session().query(ODM.Variable.code).limit(1).first() + s.test_Session().execute('Select 1') except Exception as e: - print("Connection was unsuccessful ", e.message) + print('Connection was unsuccessful {}'.format(e.message)) return False + finally: + dbconnection.closeConnection(s.test_Session) return True - def buildConnDict(self, engine, address, db, user, password): - line_dict = {} - line_dict['engine'] = engine - line_dict['user'] = user - line_dict['password'] = password - line_dict['address'] = address - line_dict['db'] = db - self._connections.append(line_dict) - self._current_connection = self._connections[-1] - return self.__buildConnectionString(line_dict) - - def getConnections(self): - return self._connections - - def getCurrentConnection(self): - return self._current_connection - - def addConnection(self, conn_dict): - """conn_dict must be a dictionary with keys: engine, user, password, address, db""" - - # remove earlier connections that are identical to this one - self.deleteConnection(conn_dict) + @classmethod + def buildConnectionString(self, engine, address, db, user, password): + return dbconnection.__buildConnectionString(dbconnection(), engine, address, db, user, password) - self._connections.append(conn_dict) - self._current_connection = self._connections[-1] + @classmethod + def closeConnection(self, session): + session.remove() + # #################### + # private variables + # # ################### - def deleteConnection(self, conn_dict): - self._connections[:] = [x for x in self._connections if x != conn_dict] + def __buildConnectionString(self, engine=None, address=None, db=None, user=None, password=None): - ## ################### - # private variables - ## ################### - - # def __buildConnectionString(self, conn_dict): - # driver = "" - # if conn_dict['engine'] == 'mssql': - # driver = "pyodbc" - # elif conn_dict['engine'] == 'mysql': - # driver = "pymysql" - # elif conn_dict['engine'] == 'postgresql': - # driver = "psycopg2" - # else: - # driver = "None" - # - # conn_string = self._connection_format % ( - # conn_dict['engine'], driver, conn_dict['user'], conn_dict['password'], conn_dict['address'], - # conn_dict['db']) - # # print conn_string - # return conn_string - - def __buildConnectionString(self, conn_dict): - # driver = "" - # print "****", conn_dict - if conn_dict['engine'] == 'mssql' and sys.platform != 'win32': - driver = "pyodbc" - #'DRIVER={FreeTDS};DSN=%s;UID=%s;PWD=%s;' % (conn_dict['address'], conn_dict['user'], conn_dict['password']) - # quoted = urllib.quote_plus('DRIVER={FreeTDS};DSN=%s;UID=%s;PWD=%s;' % (conn_dict['address'], conn_dict['user'], conn_dict['password'])) - quoted = urllib.quote_plus('DRIVER={FreeTDS};DSN=%s;UID=%s;PWD=%s;DATABASE=%s' % - (conn_dict['address'], conn_dict['user'], conn_dict['password'],conn_dict['db'],)) + if engine == 'mssql' and sys.platform != 'win32': + driver = 'pyodbc' + quoted = quote_plus('DRIVER={FreeTDS};DSN=%s;UID=%s;PWD=%s;' % (address, user, password)) conn_string = 'mssql+pyodbc:///?odbc_connect={}'.format(quoted) + elif engine == 'sqlite': + driver = 'sqlite' + conn_string = '%s:///%s' % (driver, address) else: - if conn_dict['engine'] == 'mssql': - driver = "pyodbc" - #self._connection_format = "%s+%s://%s:%s@%s/%s?driver=SQL+Server+Native+Client+10.0" - conn = "%s+%s://%s:%s@%s/%s?driver=SQL+Server" - if "sqlncli11.dll" in os.listdir("C:\\Windows\\System32"): - conn = "%s+%s://%s:%s@%s/%s?driver=SQL+Server+Native+Client+11.0" + if engine == 'mssql': + driver = 'pyodbc' + conn = '%s+%s://%s:%s@%s/%s?driver=SQL+Server' + if 'sqlncli11.dll' in os.listdir('C:\\Windows\\System32'): + conn = '%s+%s://%s:%s@%s/%s?driver=SQL+Server+Native+Client+11.0' self._connection_format = conn - conn_string = self._connection_format % ( - conn_dict['engine'], driver, conn_dict['user'], conn_dict['password'], conn_dict['address'], - conn_dict['db']) - elif conn_dict['engine'] == 'mysql': - driver = "pymysql" - conn_string = self.constringBuilder(conn_dict, driver) - elif conn_dict['engine'] == 'postgresql': - driver = "psycopg2" - conn_string = self.constringBuilder(conn_dict, driver) + conn_string = self._connection_format % (engine, driver, user, password, address, db) else: - driver = "None" - conn_string = self.constringBuilder(conn_dict, driver) - + if engine == 'mysql': + driver = 'pymysql' + elif engine == 'postgresql': + driver = 'psycopg2' + else: + driver = 'None' + conn_string = self.constringBuilder(engine, address, db, user, password, driver) - # print "******", conn_string return conn_string - def constringBuilder(self, conn_dict, driver): - if conn_dict['password'] is None or not conn_dict['password']: + def constringBuilder(self, engine=None, address=None, db=None, user=None, password=None, driver=None): + if password is None or not password: conn_string = self._connection_format_nopassword % ( - conn_dict['engine'], driver, conn_dict['user'], conn_dict['address'], - conn_dict['db']) + engine, driver, user, address, db) else: conn_string = self._connection_format % ( - conn_dict['engine'], driver, conn_dict['user'], conn_dict['password'], conn_dict['address'], - conn_dict['db']) + engine, driver, user, password, address, db) return conn_string diff --git a/odm2api/__init__.py b/odm2api/__init__.py index 8872310..830dc2e 100644 --- a/odm2api/__init__.py +++ b/odm2api/__init__.py @@ -1,7 +1,14 @@ +from __future__ import (absolute_import, division, print_function) + from odm2api.ODMconnection import SessionFactory, dbconnection from odm2api.base import serviceBase __all__ = [ 'SessionFactory', 'dbconnection', - 'serviceBase',] + 'serviceBase', +] + +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions diff --git a/odm2api/_version.py b/odm2api/_version.py new file mode 100644 index 0000000..4f6548c --- /dev/null +++ b/odm2api/_version.py @@ -0,0 +1,520 @@ + +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. Generated by +# versioneer-0.18 (https://github.com/warner/python-versioneer) + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys + + +def get_keywords(): + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "$Format:%d$" + git_full = "$Format:%H$" + git_date = "$Format:%ci$" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + +def get_config(): + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "pep440" + cfg.tag_prefix = "v" + cfg.parentdir_prefix = "" + cfg.versionfile_source = "odm2api/_version.py" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY = {} +HANDLERS = {} + + +def register_vcs_handler(vcs, method): # decorator + """Decorator to mark a method as the handler for a particular VCS.""" + def decorate(f): + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, + env=None): + """Call the given command(s).""" + assert isinstance(commands, list) + p = None + for c in commands: + try: + dispcmd = str([c] + args) + # remember shell=False, so use git.cmd on windows, not just git + p = subprocess.Popen([c] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None)) + break + except EnvironmentError: + e = sys.exc_info()[1] + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None, None + stdout = p.communicate()[0].strip() + if sys.version_info[0] >= 3: + stdout = stdout.decode() + if p.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, p.returncode + return stdout, p.returncode + + +def versions_from_parentdir(parentdir_prefix, root, verbose): + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for i in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + else: + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs): + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords = {} + try: + f = open(versionfile_abs, "r") + for line in f.readlines(): + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + f.close() + except EnvironmentError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords(keywords, tag_prefix, verbose): + """Get version information from git keywords.""" + if not keywords: + raise NotThisMethod("no keywords at all, weird") + date = keywords.get("date") + if date is not None: + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = set([r.strip() for r in refnames.strip("()").split(",")]) + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = set([r for r in refs if re.search(r'\d', r)]) + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=True) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", + "--always", "--long", + "--match", "%s*" % tag_prefix], + cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparseable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], + cwd=root) + pieces["distance"] = int(count_out) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], + cwd=root)[0].strip() + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces): + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces): + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_pre(pieces): + """TAG[.post.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post.devDISTANCE + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += ".post.dev%d" % pieces["distance"] + else: + # exception #1 + rendered = "0.post.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces): + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_old(pieces): + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Eexceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces): + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces): + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces, style): + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions(): + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for i in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} diff --git a/odm2api/base.py b/odm2api/base.py index d650720..a164a1d 100644 --- a/odm2api/base.py +++ b/odm2api/base.py @@ -1,78 +1,53 @@ - - - - -from sqlalchemy.ext.declarative import declarative_base -# #from sqlalchemy import MetaData -# from .ODMconnection import SessionFactory - -#only one copy of class at a time -class Singleton(type): - _instances = {} - - def __call__(cls, *args, **kwargs): - if cls not in cls._instances: - cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) - #print "Singleton", cls._instances[cls] - return cls._instances[cls] - -#only one copy of class with a particular connection -class SingletonByConn(type): - _instances= {} - - def __call__(cls, *args, **kwargs): - conn= args[0].engine - if (cls, conn) not in cls._instances: - - cls._instances[(cls, conn)] = super(SingletonByConn, cls).__call__(*args, **kwargs) - #print "Singleton", cls._instances[cls] - return cls._instances[(cls, conn)] +from __future__ import (absolute_import, division, print_function) class serviceBase(object): - - #__metaclass__ = SingletonByConn - - ''' - def __init__(self, session): - self._session = session - ''' def __init__(self, session_factory, debug=False): - ''' - must send in either a session_factory #TODO or a connection, exclusive or - ''' + """Must send in either a session_factory.""" - # if connection is None: self._session_factory = session_factory - # else: - # self._session_factory = SessionFactory(connection) self._session = self._session_factory.getSession() self._version = session_factory.version self._debug = debug - #self._sessiona - #self._session_factory="" - # def getSessionFactory( session = None): def getSession(self): + if self._session is None: + self._session = self._session_factory.getSession() + return self._session + def reset_session(self): + self._session = self._session_factory.getSession() -class modelBase(): - Base = declarative_base() - metadata = Base.metadata - ''' - metadata =MetaData(schema='odm2') - print "Schema:", metadata.schema +class Base(object): + from sqlalchemy.ext.declarative import declared_attr - def __init__(self, schema): - self.metadata =MetaData(schema='odm2') - ''' + @declared_attr + def __tablename__(cls): + return cls.__name__.lower() + __table_args__ = {u'schema': 'odm2'} + def __init__(self, *args, **kwargs): + for name, value in kwargs.items(): + setattr(self, name, value) + def __eq__(self, other): + return self.__dict__ == other.__dict__ + def __repr__(self): + valuedict = self.__dict__.copy() + for v in valuedict.keys(): + if 'obj' in v.lower(): + del valuedict[v] + if v == "_sa_instance_state": + del valuedict["_sa_instance_state"] + return "<%s(%s)>" % (self.__class__.__name__, str(valuedict)) +class modelBase(): + from sqlalchemy.ext.declarative import declarative_base + Base = declarative_base(cls=Base) diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..71bb791 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,21 @@ +alabaster +flake8 +flake8-builtins +flake8-comprehensions +flake8-import-order +flake8-mutable +flake8-print +flake8-quotes +mock +nbsphinx +psycopg2 +pycodestyle +pymysql +pytest +pytest-cov +sphinx +# FIXME: I am not sure these are needed. +# pysqlite +# sqlite +# pyspatialite +# mysql-python diff --git a/requirements.txt b/requirements.txt index 1aa136d..7e74829 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,3 @@ pyodbc -six sqlalchemy --e git+https://github.com/ODM2/geoalchemy.git@odm2#egg=geoalchemy-0.7.3 -shapely pandas -#psycopg2 # Commented out because I could not pip install it. diff --git a/requirements_tests.txt b/requirements_tests.txt deleted file mode 100644 index db6f2b8..0000000 --- a/requirements_tests.txt +++ /dev/null @@ -1,13 +0,0 @@ --r requirements.txt -pytest -pytest-cov -mock -#db support -pymysql -pysqlite -pymssql -psycopg2 -#pyspatialite -mysql-python - - diff --git a/setup.cfg b/setup.cfg index 7489038..18632d1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1 +1,12 @@ -[bdist_wheel] \ No newline at end of file +# See the docstring in versioneer.py for instructions. Note that you must +# re-run 'versioneer.py setup' after changing this section, and commit the +# resulting files. + +[versioneer] +VCS = git +style = pep440 +versionfile_source = odm2api/_version.py +versionfile_build = odm2api/_version.py +tag_prefix = v +parentdir_prefix = + diff --git a/setup.py b/setup.py index 5cccf8c..309ef6c 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,5 @@ +from __future__ import (absolute_import, division, print_function) + """A setuptools based setup module. See: @@ -5,135 +7,51 @@ https://github.com/pypa/sampleproject """ -''' -to install in development mode, run the following code from command line -"python setup.py develop" -''' - -# Always prefer setuptools over distutils -from setuptools import setup, find_packages -# To use a consistent encoding +import os from codecs import open -from os import path -here = path.abspath(path.dirname(__file__)) +from setuptools import find_packages, setup -from pip.req import parse_requirements -install_reqs = parse_requirements('requirements.txt', session=False) -reqs = [str(ir.req) for ir in install_reqs] +import versioneer -# Get the long description from the relevant file -with open(path.join(here, 'README.md'), encoding='utf-8') as f: - long_description = f.read() -#long_description = "" -setup( - name='odm2api', +here = os.path.abspath(os.path.dirname(__file__)) - # Versions should comply with PEP440. For a discussion on single-sourcing - # the version across setup.py and the project code, see - # https://packaging.python.org/en/latest/single_source_version.html - version='0.5', +# Dependencies. +with open('requirements.txt') as f: + requirements = f.readlines() +install_requires = [t.strip() for t in requirements] - description='A Python-based application programmers interface for the Observations Data Model 2 (ODM2) ', - long_description=long_description, +with open(os.path.join(here, 'README.md'), encoding='utf-8') as f: + long_description = f.read() - # The project's main homepage. +setup( + name='odm2api', + version=versioneer.get_version(), + description='Python interface for the Observations Data Model 2 (ODM2)', + long_description=long_description, url='https://github.com/ODM2/ODM2PythonAPI', - - # Author details author='ODM2 team-Stephanie Reeder', author_email='stephanie.reeder@usu.edu', - - # note: maintainer gets listed as author in PKG-INFO, so leaving - # this commented out for now maintainer='David Valentine', maintainer_email='david.valentine@gmail.com', - - # Choose your license - license='BSD-3-Clause', - - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers + license='BSD', classifiers=[ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable 'Development Status :: 3 - Alpha', - - # Indicate who your project is intended for 'Intended Audience :: Developers', 'Topic :: Software Development :: Build Tools', - - # Pick your license as you wish (should match "license" above) 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', - # Specify the Python versions you support here. In particular, ensure - # that you indicate whether you support Python 2, Python 3 or both. 'Programming Language :: Python :: 2.7', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Scientific/Engineering' ], - - # What does your project relate to? keywords='Observations Data Model ODM2', - - # You can just specify the packages manually here if your project is - # simple. Or you can use find_packages(). - - packages=find_packages(exclude=['Examples', 'setup', 'tests*', 'Forms']), - - # List run-time dependencies here. These will be installed by pip when - # your project is installed. For an analysis of "install_requires" vs pip's - # requirements files see: - # https://packaging.python.org/en/latest/requirements.html - - install_requires=install_reqs, - # install_requires=[ - # 'pyodbc', - # 'six', - # 'sqlalchemy', - # 'geoalchemy>=0.7.3', - # 'shapely', - # 'pandas', - # ], - # dependency_links- geoalchemy from the ODM repository - dependency_links=[ - "git+https://github.com/ODM2/geoalchemy.git@v0.7.3#egg=geoalchemy-0.7.3" - ], - - # List additional groups of dependencies here (e.g. development - # dependencies). You can install these using the following syntax, - # for example: - # $ pip install -e .[dev,test] + packages=find_packages(exclude=['samplefiles', 'setup', 'tests*', 'Forms']), + install_requires=install_requires, extras_require={ 'mysql': ['pymysql'], 'postgis': ['psycopg2'], - 'sqlite': ['pyspatialite >=3.0.0'], # need to look at: http://www.gaia-gis.it/spatialite-2.4.0-4/splite-python.html - 'test': ['coverage'], + 'sqlite': ['pyspatialite >=3.0.0'], }, - - # If there are data files included in your packages that need to be - # installed, specify them here. If using Python 2.6 or less, then these - # have to be included in MANIFEST.in as well. - # - # package_data={ - # 'sample': ['package_data.dat'], - # }, - - # Although 'package_data' is the preferred approach, in some case you may - # need to place data files outside of your packages. See: - # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa - # In this case, 'data_file' will be installed into '/my_data' - - # data_files=[('my_data', ['data/data_file'])], - - # To provide executable scripts, use entry points in preference to the - # "scripts" keyword. Entry points provide cross-platform support and allow - # pip to create the appropriate form of executable for the target platform. - - # entry_points={ - # 'console_scripts': [ - # 'sample=sample:main', - # ], - # }, + cmdclass=versioneer.get_cmdclass(), ) diff --git a/tests/__init__.py b/tests/__init__.py index 8b13789..78f3bf2 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1 @@ - +from __future__ import (absolute_import, division, print_function) diff --git a/tests/schemas/__init__.py b/tests/schemas/__init__.py index e69de29..78f3bf2 100644 --- a/tests/schemas/__init__.py +++ b/tests/schemas/__init__.py @@ -0,0 +1 @@ +from __future__ import (absolute_import, division, print_function) diff --git a/tests/schemas/postgresql/__init__.py b/tests/schemas/postgresql/__init__.py index e69de29..78f3bf2 100644 --- a/tests/schemas/postgresql/__init__.py +++ b/tests/schemas/postgresql/__init__.py @@ -0,0 +1 @@ +from __future__ import (absolute_import, division, print_function) diff --git a/tests/schemas/postgresql/olderversions/DbWrench_DDL_postprocess.py b/tests/schemas/postgresql/olderversions/DbWrench_DDL_postprocess.py index 0c9de9b..6a964d7 100644 --- a/tests/schemas/postgresql/olderversions/DbWrench_DDL_postprocess.py +++ b/tests/schemas/postgresql/olderversions/DbWrench_DDL_postprocess.py @@ -1,3 +1,5 @@ +from __future__ import (absolute_import, division, print_function) + """ DbWrench_DDL_postprocess.py Emilio Mayorga (UW/APL) 8/15-18/2014 @@ -5,7 +7,7 @@ generate a new, blank ODM2 database following ODM2 conventions. Specifically: 1. All entity names will be lowercase 2. All entities will be under a single schema -3. The field samplingfeatures.featuregeometry will be PostGIS geometry field constrained +3. The field samplingfeatures.featuregeometry will be PostGIS geometry field constrained to be 2D, but otherwise free to store any project (eg, epsg:4326) and to accept any geometry type (point, line, polygon, and collections thereof [multi-polygon, etc]) @@ -26,20 +28,20 @@ # =============== USER (run-time) CHANGES ================= # DDL input file name -ddlfile = "ODM2_DDL_for_PostgreSQL9.3PostGIS2.1.sql" +ddlfile = 'ODM2_DDL_for_PostgreSQL9.3PostGIS2.1.sql' # DDL output file name -ddlppfile = "ODM2_DDL_for_PostgreSQL9.3PostGIS2.1_postprocessed.sql" +ddlppfile = 'ODM2_DDL_for_PostgreSQL9.3PostGIS2.1_postprocessed.sql' -newschemaname = "odm2" -odmversion = "2.0" -odm2infodct = {'schema':newschemaname, 'version':odmversion} +newschemaname = 'odm2' +odmversion = '2.0' +odm2infodct = {'schema': newschemaname, 'version': odmversion} # ========================================================= pre_block = """ /* Post-processed DDL based on DbWrench export. 2014-8-18 10pm PDT */ --- IF THIS DDL SCRIPT IS TO *CREATE* THE DATABASE ITSELF, --- WILL NEED TO FIRST KNOW THE DATABASE NAME AND ROLES TO BE USED. +-- IF THIS DDL SCRIPT IS TO *CREATE* THE DATABASE ITSELF, +-- WILL NEED TO FIRST KNOW THE DATABASE NAME AND ROLES TO BE USED. /* Add single base schema for all odm2 entities */ CREATE SCHEMA %(schema)s; @@ -48,14 +50,15 @@ post_block = """/* ** Set up samplingfeatures.featuregeometry as a heterogeneous, 2D PostGIS geom field. */ ALTER TABLE %(schema)s.samplingfeatures ALTER COLUMN featuregeometry TYPE geometry; -ALTER TABLE %(schema)s.samplingfeatures ADD CONSTRAINT +ALTER TABLE %(schema)s.samplingfeatures ADD CONSTRAINT enforce_dims_featuregeometry CHECK (st_ndims(featuregeometry) = 2); CREATE INDEX idx_samplingfeature_featuregeom ON %(schema)s.samplingfeatures USING gist (featuregeometry); -- Populate and tweak geometry_columns SELECT Populate_Geometry_Columns(); -- But it assigned a POINT type to %(schema)s.samplingfeatures. Need instead to use the generic -- 'geometries', to accept any type (point, line, polygon, and collections thereof [multi-polygon, etc]) -UPDATE public.geometry_columns SET type = 'GEOMETRY' WHERE f_table_schema = '%(schema)s' AND f_table_name = 'samplingfeatures'; +UPDATE public.geometry_columns SET +type = 'GEOMETRY' WHERE f_table_schema = '%(schema)s' AND f_table_name = 'samplingfeatures'; """ % odm2infodct # Relies on these assumptions: @@ -78,10 +81,10 @@ # Insert pre and post blocks, and the modified DDL lines in between ddl_ppf = open(ddlppfile, 'w') ddl_ppf.write(pre_block) -ddl_ppf.write("/* ================================================================\n") -ddl_ppf.write(" ================================================================ */\n\n") +ddl_ppf.write('/* ================================================================\n') +ddl_ppf.write(' ================================================================ */\n\n') ddl_ppf.writelines(ddl_pp_lines) -ddl_ppf.write("\n/* ================================================================\n") -ddl_ppf.write(" ================================================================ */\n\n") +ddl_ppf.write('\n/* ================================================================\n') +ddl_ppf.write(' ================================================================ */\n\n') ddl_ppf.write(post_block) ddl_ppf.close() diff --git a/tests/schemas/postgresql/olderversions/__init__.py b/tests/schemas/postgresql/olderversions/__init__.py index e69de29..78f3bf2 100644 --- a/tests/schemas/postgresql/olderversions/__init__.py +++ b/tests/schemas/postgresql/olderversions/__init__.py @@ -0,0 +1 @@ +from __future__ import (absolute_import, division, print_function) diff --git a/tests/test_SessionFactory.py b/tests/test_SessionFactory.py index ee7b412..adcb446 100644 --- a/tests/test_SessionFactory.py +++ b/tests/test_SessionFactory.py @@ -1,72 +1,48 @@ -__author__ = 'valentine' +from __future__ import (absolute_import, division, print_function) + +from odm2api.ODM2.models import CVElevationDatum, setSchema from odm2api.ODMconnection import SessionFactory -from odm2api.ODM2.models import * + import pytest -from sqlalchemy.engine import reflection -# assumes that pytest is being run from ODM2PythonAPI director -# [name, driver, connectionstring ] +__author__ = 'valentine' + + dbs_readonly = [ - # ['mysql', 'localhost', 'odm2', 'ODM', 'odm'], ['mysql:ODM@Localhost/', 'mysql', 'mysql+pymysql://ODM:odm@localhost/'], ['mysql"root@Localhost/', 'mysql', 'mysql+pymysql://root@localhost/'], ['mysql:ODM@Localhost/odm2', 'mysql', 'mysql+pymysql://ODM:odm@localhost/odm2'], ['mysql"root@Localhost/odm2', 'mysql', 'mysql+pymysql://root@localhost/odm2'], - [' mysql + mysqldb:', 'mysql', 'mysql+mysqldb://root@localhost/odm2'], - #'mysql+pymysql://ODM:odm@127.0.0.1/odm2' - ['postgresql_marchantariats_none', 'postgresql', 'postgresql+psycopg2://postgres:None@localhost/marchantariats', 'marchantariats', 'postgres', None], - ['postgresql_marchantariats_empty', 'postgresql', 'postgresql+psycopg2://postgres@localhost/marchantariats', 'marchantariats', 'postgres', None], - #'postgresql+psycopg2://postgres:None@localhost/marchantariats' - - # ["mssql_pyodbc_azure", "mssql", "mssql+pyodbc:///?odbc_connect=DRIVER%3D%7BFreeTDS%7D%3BDSN%3Dazure%3BUID%3Dweb%3BPWD%3D1Forgetit%21%3B" , 'odm2', 'web', '1Forgetit!'], - # ["mssql_pyodbc2_azure", "mssql", "mssql+pyodbc:///?odbc_connect=DRIVER%3DFreeTDS%3BSERVERNAME%3Dnrb8xkgxaj.database.windows.net%3BUID%3Dweb@nrb8xkgxaj%3BPWD%3D1Forgetit!%3BDATABASE%3Dodm2", ], - # ["mssql_pyodbc3_azure", "mssql", "mssql+pyodbc:///?odbc_connect=DRIVER%3D{FreeTDS}%3BSERVERNAME%3Dnrb8xkgxaj.database.windows.net%3BUID%3Dweb%3DPWD%3D1Forgetit!%3BDATABASE%3Dodm2",], - #'mssql+pyodbc:///?odbc_connect=DRIVER%3D%7BFreeTDS%7D%3BDSN%3Dnrb8xkgxaj.database.windows.net%3BUID%3Dweb%3BPWD%3D1Forgetit%21%3B' - # ["mssql_pyodbc_moonstone", "mssql","mssql+pyodbc:///?odbc_connect=DRIVER%3D%7BFreeTDS%7D%3BDSN%3Dmoonstone%3BUID%3Dwebservice%3BPWD%3Dwebservice%21%3BDATABASE=odm2",], - # ["mssql_pyodbc2", "mssql", "mssql+pyodbc:///?odbc_connect=DRIVER={FreeTDS};SERVERNAME=moonstone.ucsd.edu;UID=webservice;PWD=webservice;DATABASE=odm2", ], - # ["pymssql_azre", "mssql", "mssql+pymssql://web@nrb8xkgxaj:1Forgetit!@kyle?charset=utf8", ], - # ["pymssql_azre2", "mssql", "mssql+pymssql://web:1Forgetit!@kyle?charset=utf8",], - # ["pymssql_moonstone", "mssql", "mssql+pymssql://webservice:webservice@moonstone?charset=utf8"], - # ["mssql", "localhost", 'odm2', 'odm', 'odm'], - # ["sqlite", "./tests/spatialite/odm2_test.sqlite", None, None, None], - ["sqlite_wof", "sqlite","sqlite:///./tests/spatialite/wof2odm/ODM2.sqlite", None, None, None] - #'sqlite:///./tests/spatialite/wof2odm/ODM2.sqlite' + ['postgresql_marchantariats_none', 'postgresql', + 'postgresql+psycopg2://postgres:None@localhost/marchantariats', + 'marchantariats', 'postgres', None], + ['postgresql_marchantariats_empty', 'postgresql', + 'postgresql+psycopg2://postgres@localhost/marchantariats', + 'marchantariats', 'postgres', None], + ['sqlite_wof', 'sqlite', 'sqlite:///./tests/spatialite/wof2odm/ODM2.sqlite', None, None, None] ] -dbs_test = [ - ["sqlite_test","sqlite" "./tests/spatialite/odm2_test.sqlite", None, None, None] +dbs_test = [ + ['sqlite_test', 'sqlite' './tests/spatialite/odm2_test.sqlite', None, None, None] ] + + class aSessionFactory: def __init__(self, request): - #session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm') db = request.param - print ("dbtype", db[0], db[1] ) - #session_factory = dbconnection.createConnection(db[0],db[1],db[2],db[3],db[4], echo=True) + print ('dbtype', db[0], db[1]) session_factory = SessionFactory(db[2]) setSchema(session_factory.engine) - assert session_factory is not None, ("failed to create a session for ", db[0], db[1]) -# assert session_factory.engine is not None, ("failed: session has no engine ", db[0], db[1]) -# - # insp = reflection.Inspector.from_engine(session_factory.engine) -# tables = insp.get_table_names() - + assert session_factory is not None, ('failed to create a session for ', db[0], db[1]) self.session = session_factory.getSession() -# -# params=["sqlite+pysqlite:///../../ODM2PythonAPI/tests/spatialite/odm2_test.sqlite", "mail.python.org"]) -@pytest.fixture(scope="session", params = dbs_readonly) +@pytest.fixture(scope='session', params=dbs_readonly) def setup(request): return aSessionFactory(request) -#connect to all 4 database types( mssql, mysql, postgresql, sqlite, mssql on mac) def test_aSessionFactory(setup): - - q= setup.session.query(CVElevationDatum) - results= q.all() - #print results + q = setup.session.query(CVElevationDatum) + results = q.all() assert len(results) > 0 - - - diff --git a/tests/test_connection.py b/tests/test_connection.py index 6aae065..e233eff 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -1,57 +1,52 @@ -__author__ = 'valentine' +from __future__ import (absolute_import, division, print_function) + +from odm2api.ODM2.models import CVElevationDatum from odm2api.ODMconnection import dbconnection -from odm2api.ODM2.models import * import pytest from sqlalchemy.engine import reflection -# assumes that pytest is being run from ODM2PythonAPI director -# [ name, driver, server, database, user, password ] + +__author__ = 'valentine' + dbs_readonly = [ - # ['mysql', 'localhost', 'odm2', 'ODM', 'odm'], ['mysql_odm2_odm', 'mysql', 'localhost', 'odm2', 'ODM', 'odm'], - ['mysql_odm2_root','mysql', 'localhost', 'odm2', 'root', None], - ['postgresql_marchantariats','postgresql', 'localhost', 'marchantariats', 'postgres', 'iforget'], - -# bet the @ is scrwing thing up - # ["mssql", "nrb8xkgxaj.database.windows.net" , 'odm2', 'web@nrb8xkgxaj', '1Forgetit!'], - # ["mssql_azure", "mssql", "azure", 'odm2', 'web@nrb8xkgxaj', '1Forgetit!'], -# ["mssql", "localhost", 'odm2', 'odm', 'odm'], - # ["sqlite", "./tests/spatialite/odm2_test.sqlite", None, None, None], - ["sqlite_wof","sqlite", "./tests/spatialite/wof2odm/ODM2.sqlite", None, None, None] + ['mysql_odm2_root', 'mysql', 'localhost', 'odm2', 'root', None], + ['postgresql_marchantariats', 'postgresql', 'localhost', 'marchantariats', 'postgres', 'iforget'], + ['sqlite_wof', 'sqlite', './tests/spatialite/wof2odm/ODM2.sqlite', None, None, None] ] -dbs_test = [ - ["sqlite", "./tests/spatialite/odm2_test.sqlite", None, None, None] +dbs_test = [ + ['sqlite_memory', 'sqlite', ':memory:', None, None, None] ] + + class Connection: def __init__(self, request): - #session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm') db = request.param - print ("dbtype", db[0], db[1] ) - session_factory = dbconnection.createConnection(db[1],db[2],db[3],db[4],db[5], echo=True) - assert session_factory is not None, ("failed to create a session for ", db[0], db[1]) - assert session_factory.engine is not None, ("failed: session has no engine ", db[0], db[1]) + print ('dbtype', db[0], db[1]) + session_factory = dbconnection.createConnection(db[1], db[2], db[3], db[4], db[5], echo=True) + assert session_factory is not None, ('failed to create a session for ', db[0], db[1]) + assert session_factory.engine is not None, ('failed: session has no engine ', db[0], db[1]) insp = reflection.Inspector.from_engine(session_factory.engine) - tables = insp.get_table_names() + insp.get_table_names() self.session = session_factory.getSession() - # self.session = session_factory.test_Session() -# -# params=["sqlite+pysqlite:///../../ODM2PythonAPI/tests/spatialite/odm2_test.sqlite", "mail.python.org"]) -@pytest.fixture(scope="session", params = dbs_readonly) +@pytest.fixture(scope='session', params=dbs_readonly) def setup(request): return Connection(request) -#connect to all 4 database types( mssql, mysql, postgresql, sqlite, mssql on mac) def test_connection(setup): - - q= setup.session.query(CVElevationDatum) - results= q.all() - #print results + q = setup.session.query(CVElevationDatum) + results = q.all() assert len(results) > 0 +def test_create_all_schema(): + pass + +def test_create_all_no_schema(): + pass diff --git a/tests/test_example.py b/tests/test_example.py deleted file mode 100644 index 7525f4d..0000000 --- a/tests/test_example.py +++ /dev/null @@ -1,88 +0,0 @@ -# run with 'py.test -s test_example.py' - -def multiply(x, y): - return x * y - - -############ -# Fixtures # -############ -def setup_module(module): - print "setup_module module:%s" % module.__name__ - - -def teardown_module(module): - print "teardown_module module:%s" % module.__name__ - - -def setup_function(function): - print "setup_function function:%s" % function.__name__ - - -def teardown_function(function): - print "teardown_function function:%s" % function.__name__ - - -######### -# Tests # -######### - - -def test_numbers_3_4(): - assert multiply(3, 4) == 12 - - -def test_strings_a_3(): - assert multiply('a', 3) == 'aaa' - - -############ -# Funcargs # -############ -def pytest_funcarg__myfuncarg(request): - return 42 - - -def test_function(myfuncarg): - assert myfuncarg == 42 - - -def pytest_generate_tests(metafunc): - if "numiter" in metafunc.funcargnames: - metafunc.parametrize("numiter", range(10)) - - -def test_func(numiter): - assert numiter < 10 - - -############## -# Test Class # -############## -class TestMult: - def setup(self): - print "setup class:TestStuff" - - def teardown(self): - print "teardown class:TestStuff" - - def setup_class(cls): - print "setup_class class:%s" % cls.__name__ - - def teardown_class(cls): - print "teardown_class class:%s" % cls.__name__ - - def setup_method(self, method): - print "setup_method method:%s" % method.__name__ - - def teardown_method(self, method): - print "teardown_method method:%s" % method.__name__ - - - def test_numbers_5_6(self): - print 'test_numbers_5_6 <================== actual test code' - assert multiply(5, 6) == 30 - - def test_string_b_2(self): - print 'test_string_b_2 <================== actual test code' - assert multiply('b', 2) == 'bb' \ No newline at end of file diff --git a/tests/test_odm1/__init__.py b/tests/test_odm1/__init__.py deleted file mode 100644 index a24dbc6..0000000 --- a/tests/test_odm1/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__author__ = 'stephanie' diff --git a/tests/test_odm1/test_odmdata/__init__.py b/tests/test_odm1/test_odmdata/__init__.py deleted file mode 100644 index 6db40e4..0000000 --- a/tests/test_odm1/test_odmdata/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__author__ = 'Stephanie' diff --git a/tests/test_odm1/test_odmdata/test_FreeTDS_1_1.py b/tests/test_odm1/test_odmdata/test_FreeTDS_1_1.py deleted file mode 100644 index 294b8df..0000000 --- a/tests/test_odm1/test_odmdata/test_FreeTDS_1_1.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -from odm2api.ODM1_1_1.models import Variable, Series -from odm2api.ODM1_1_1.services import SeriesService -from odm2api.ODMconnection import SessionFactory -from tests import test_util1_1_1 as test_util - -#import wx -from tests.test_util1_1_1 import build_db -import urllib -import sqlalchemy -from sqlalchemy.orm import sessionmaker -import pytest - -@pytest.mark.skipif(True, - reason="ODM1.1 shim is out of date") -class TestFreeTDS_1_1: - def setup(self): - # connection string - - # create engine - #quoted = urllib.quote_plus('DRIVER={FreeTDS};Server=iutahqc.uwrl.usu.edu;Database=iUTAH_Logan_OD;UID=qc;PWD=iUTAH123!!;TDS_Version=8.0;Port=1433;') - quoted = urllib.quote_plus('DRIVER={FreeTDS};DSN=iutahqc;UID=qc;PWD=iUTAH123!!;') - engine = sqlalchemy.create_engine('mssql+pyodbc:///?odbc_connect={}'.format(quoted)) - # conn = engine.connect() - # q = conn.execute("select * from variables") - print "engine:", engine - assert engine - Session = sessionmaker(bind=engine) - assert Session - session = Session() - assert session - q= session.query(Variable.Variable).all() - print "q:", type(q), dir(q) - for i in q: - print i - #conn.close() - q= session.query(Series.Series).all() - for i in q[:10]: - print i - assert q - print engine - - def test_connection(self): - pass diff --git a/tests/test_odm1/test_odmdata/test_data_value_1_1.py b/tests/test_odm1/test_odmdata/test_data_value_1_1.py deleted file mode 100644 index 18aa408..0000000 --- a/tests/test_odm1/test_odmdata/test_data_value_1_1.py +++ /dev/null @@ -1,52 +0,0 @@ -from odm2api.ODM1_1_1.models import * - -from odm2api.ODMconnection import SessionFactory - -from tests import test_util1_1_1 as test_util - -import pytest - -@pytest.mark.skipif(True, - reason="ODM1.1 shim is out of date") -class TestDataValue_1_1: - def setup(self): - self.connection_string = "sqlite:///:memory:" - session_factory = SessionFactory(self.connection_string, echo=False) - test_util.build_db(session_factory.engine) - self.session = session_factory.getSession() - self.series = test_util.add_series(self.session) - self.data_values = self.series.data_values - - def test_create_data_values(self): - assert self.data_values != [] - assert self.data_values[0].id != None - - def test_site_relationship(self): - site = self.data_values[0].site - assert site != None - assert site.id != None - - def test_variable_relationship(self): - var = self.data_values[0].variable - assert var != None - assert var.id != None - - def test_method_relationship(self): - method = self.data_values[0].method - assert method != None - assert method.id != None - - def test_source_relationship(self): - source = self.data_values[0].source - assert source != None - assert source.id != None - - def test_qcl_relationship(self): - qcl = self.data_values[0].quality_control_level - assert qcl != None - assert qcl.id != None - - def test_list_repr(self): - dv = self.data_values[0] - assert len(dv.list_repr()) == 17 - assert dv.id in dv.list_repr() \ No newline at end of file diff --git a/tests/test_odm1/test_odmdata/test_memory_db_1_1.py b/tests/test_odm1/test_odmdata/test_memory_db_1_1.py deleted file mode 100644 index 80eefc1..0000000 --- a/tests/test_odm1/test_odmdata/test_memory_db_1_1.py +++ /dev/null @@ -1,64 +0,0 @@ -import pytest - -#from odm2api.ODM1_1_1 import memory_database as MemoryDatabase -from odm2api.ODM1_1_1.services import SeriesService -from tests import test_util1_1_1 as test_util - -import datetime - -import pytest - -@pytest.mark.skipif(True, - reason="ODM1.1 shim is out of date") -class TestMemoryDB_1_1: - def setup(self): - self.connection_string = "sqlite:///:memory:" - self.series_service = SeriesService(connection_string=self.connection_string, debug=False) - self.session = self.series_service._session_factory.get_session() - engine = self.series_service._session_factory.engine - test_util.build_db(engine) - - self.memory_db = MemoryDatabase() - - self.memory_db.set_series_service(self.series_service) - self.series = test_util.add_series(self.session) - self.memory_db.initEditValues(self.series.id) - - def test_get_data_values(self): - dvs = self.memory_db.getDataValuesDF() - assert len(dvs) == 10 - - def test_update_points(self): - self.memory_db.update([{"value":15,"id":1}]) - dvs = self.memory_db.getDataValuesDF() - print dvs["DataValue"] - assert dvs["DataValue"][1-1] == 9 - - def test_update_value(self): - self.memory_db.updateValue([1],'+', 5 ) - dvs = self.memory_db.getDataValuesDF() - assert dvs["DataValue"][1-1] == 9 - - def test_add_points(self): - #with pytest.raises(NotImplementedError): - point = [('-9999', None, datetime.datetime(2011, 3, 25, 0, 0), '-7', datetime.datetime(2015, 3, 25, 7, 0), None, - None, u'nc', None, None, self.series.site_id, self.series.variable_id, self.series.method_id, - self.series.source_id, self.series.quality_control_level_id)] - self.memory_db.addPoints(point) - dvs = self.memory_db.getDataValuesDF() - - assert len(dvs) == 11 - assert dvs["DataValue"][-1] == -9999 - - def test_update_flag(self): - self.memory_db.updateFlag([5], '50') - dvs=self.memory_db.getDataValuesDF() - assert dvs["QualifierID"][5-1] == '50' - - - def test_delete_points(self): - stlen= len(self.memory_db.getDataValuesDF()) - self.memory_db.delete([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) - dvs = self.memory_db.getDataValuesDF() - assert len(dvs) == stlen-10 - diff --git a/tests/test_odm1/test_odmdata/test_pandas_memory_db_1_1.py b/tests/test_odm1/test_odmdata/test_pandas_memory_db_1_1.py deleted file mode 100644 index 701f2fa..0000000 --- a/tests/test_odm1/test_odmdata/test_pandas_memory_db_1_1.py +++ /dev/null @@ -1,40 +0,0 @@ -from odm2api.ODMconnection import SessionFactory - -from odm2api.ODM1_1_1.models import Series -from odm2api.ODM1_1_1.services import SeriesService - -from tests import test_util1_1_1 as test_util - -__author__ = 'jmeline' - -""" -Sample ODM Database connection and data insertion for unittesting against -""" -import pytest - -@pytest.mark.skipif(True, - reason="ODM1.1 shim is out of date") -class TestPandasMemoryDB_1_1: - """ - Test to Load up a series from a dataframe and load it into an in memory database - """ - def setup(self): - self.connection_string = "sqlite:///:memory:" - self.session_factory = SessionFactory(self.connection_string, echo=False) - self.session = self.session_factory.get_session() - - self.series_service = SeriesService(connection_string=self.connection_string) - engine = self.session_factory.engine - test_util.build_db(engine) - - def test_build_series(self): - dvs = 100 - self.series = test_util.add_series_bulk_data(self.session, dvs_size=dvs) - assert self.series - assert len(self.series.data_values) == dvs - - - - - - diff --git a/tests/test_odm1/test_odmdata/test_series_1_1.py b/tests/test_odm1/test_odmdata/test_series_1_1.py deleted file mode 100644 index 7ac4751..0000000 --- a/tests/test_odm1/test_odmdata/test_series_1_1.py +++ /dev/null @@ -1,63 +0,0 @@ -from odm2api.ODM1_1_1.models import * -#from odm2api.ODM1_1_1.odmdata import copy_series -from odm2api.ODMconnection import SessionFactory - -from tests import test_util1_1_1 as test_util - -import pytest - -@pytest.mark.skipif(True, - reason="ODM1.1 shim is out of date") -class TestSeries_1_1: - def setup(self): - self.connection_string = "sqlite:///:memory:" - session_factory = SessionFactory(self.connection_string, echo=False) - test_util.build_db(session_factory.engine) - self.session = session_factory.get_session() - self.series = test_util.add_series(self.session) - - def test_create_series(self): - assert self.series != None - assert self.series.id != None - - def test_data_values_relationship(self): - assert self.series.data_values != None - assert len(self.series.data_values) != 0 - - def test_site_relationship(self): - site = self.series.site - assert site != None - - def test_variable_relationship(self): - var = self.series.variable - assert var != None - - def test_method_relationship(self): - method = self.series.method - assert method != None - - def test_source_relationship(self): - source = self.series.source - assert source != None - - def test_qcl_relationship(self): - qcl = self.series.quality_control_level - assert qcl != None - - def test_get_table_cols(self): - assert len(self.series.get_table_columns()) == 30 - assert "SeriesID" in self.series.get_table_columns() - assert "ValueCount" in self.series.get_table_columns() - - def test_list_repr(self): - assert len(self.series.list_repr()) == 30 - assert self.series.id == self.series.list_repr()[0] - - def test_copy_series(self): - copy = copy_series(self.series) - assert copy.id != self.series.id - assert copy.site_id == self.series.site_id - assert copy.variable_id == self.series.variable_id - assert copy.method_id == self.series.method_id - assert copy.source_id == self.series.source_id - assert copy.quality_control_level_id == self.series.quality_control_level_id \ No newline at end of file diff --git a/tests/test_odm1/test_odmdata/test_session_factory_1_1.py b/tests/test_odm1/test_odmdata/test_session_factory_1_1.py deleted file mode 100644 index 6eca74d..0000000 --- a/tests/test_odm1/test_odmdata/test_session_factory_1_1.py +++ /dev/null @@ -1,18 +0,0 @@ -from odm2api.ODMconnection import SessionFactory - -import pytest - -@pytest.mark.skipif(True, - reason="ODM1.1 shim is out of date") -class TestSessionFactory_1_1: - def setup(self): - self.connection_string = "sqlite:///:memory:" - self.session_factory = SessionFactory(self.connection_string, echo=True) - - def test_create_session_factory(self): - assert repr(self.session_factory) == "" % self.connection_string - assert self.session_factory.Session != None - - def test_get_session(self): - session = self.session_factory.get_session() - assert 'sqlalchemy.orm.session.Session' in repr(session) \ No newline at end of file diff --git a/tests/test_odm1/test_odmservices/__init__.py b/tests/test_odm1/test_odmservices/__init__.py deleted file mode 100644 index b1e4b9d..0000000 --- a/tests/test_odm1/test_odmservices/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__author__ = 'Jacob' diff --git a/tests/test_odm1/test_odmservices/test_cv_service_1_1.py b/tests/test_odm1/test_odmservices/test_cv_service_1_1.py deleted file mode 100644 index 9dbdad0..0000000 --- a/tests/test_odm1/test_odmservices/test_cv_service_1_1.py +++ /dev/null @@ -1,142 +0,0 @@ -import pytest -import sqlalchemy.orm.exc -from odm2api.ODM1_1_1.models import Qualifier -#from odm2api.ODM1_1_1.services import CVService - -from tests import test_util1_1_1 as test_util - - -session = None - - -@pytest.mark.skipif(True, - reason="ODM1.1 shim is out of date") -class TestCVService_1_1: - def setup(self): - self.connection_string = "sqlite:///:memory:" - self.cv_service = CVService(self.connection_string, debug=False) - self.session = self.cv_service._session_factory.get_session() - engine = self.cv_service._session_factory.engine - test_util.build_db(engine) - - def test_get_vertical_datum_cvs_1_1(self): - assert self.cv_service.get_vertical_datum_cvs() == [] - - vert_dat = test_util.add_vertical_datum_cv(self.session) - db_vert_dat = self.cv_service.get_vertical_datum_cvs()[0] - assert vert_dat.term == db_vert_dat.term - - def test_get_samples_1_1(self): - assert self.cv_service.get_samples() == [] - - lab_method = test_util.add_lab_method(self.session) - sample = test_util.add_sample(self.session, lab_method.id) - - db_sample = self.cv_service.get_samples()[0] - assert sample.id == db_sample.id - assert sample.lab_method_id == db_sample.lab_method_id - - - - def test_get_site_type_cvs_1_1(self): - assert self.cv_service.get_site_type_cvs() == [] - - st_cv = test_util.add_site_type_cv(self.session) - db_st_cv = self.cv_service.get_site_type_cvs()[0] - assert st_cv.term == db_st_cv.term - - def test_get_variable_name_cvs_1_1(self): - assert self.cv_service.get_variable_name_cvs() == [] - - var_name_cv = test_util.add_variable_name_cv(self.session) - db_var_name_cv = self.cv_service.get_variable_name_cvs()[0] - assert var_name_cv.term == db_var_name_cv.term - - def test_get_offset_type_cvs_1_1(self): - assert self.cv_service.get_offset_type_cvs() == [] - - unit = test_util.add_unit_1_1(self.session) - offset = test_util.add_offset_type_cv(self.session, unit.id) - - db_offset = self.cv_service.get_offset_type_cvs()[0] - assert offset.id == db_offset.id - assert offset.unit_id == db_offset.unit_id - - def test_get_speciation_cvs_1_1(self): - assert self.cv_service.get_speciation_cvs() == [] - - speciation = test_util.add_speciation_cv(self.session) - db_speciation = self.cv_service.get_speciation_cvs()[0] - assert speciation.term == db_speciation.term - - def test_get_sample_medium_cvs_1_1(self): - assert self.cv_service.get_sample_medium_cvs() == [] - - sample_medium = test_util.add_sample_medium_cv(self.session) - db_sample_medium = self.cv_service.get_sample_medium_cvs()[0] - assert sample_medium.term == db_sample_medium.term - - def test_get_value_type_cvs_1_1(self): - assert self.cv_service.get_value_type_cvs() == [] - - value_type = test_util.add_value_type_cv(self.session) - db_val_type = self.cv_service.get_value_type_cvs()[0] - assert value_type.term == db_val_type.term - - def test_get_data_type_cvs_1_1(self): - assert self.cv_service.get_data_type_cvs() == [] - - data_type = test_util.add_data_type_cv(self.session) - db_data_type = self.cv_service.get_data_type_cvs()[0] - assert data_type.term == db_data_type.term - - def test_get_general_category_cvs_1_1(self): - assert self.cv_service.get_general_category_cvs() == [] - - gen_cat = test_util.add_general_category_cv(self.session) - db_gen_cat = self.cv_service.get_general_category_cvs()[0] - assert gen_cat.term == db_gen_cat.term - - def test_get_censor_code_cvs_1_1(self): - assert self.cv_service.get_censor_code_cvs() == [] - - censor_code = test_util.add_censor_code_cv(self.session) - db_censor_code = self.cv_service.get_censor_code_cvs()[0] - assert censor_code.term == db_censor_code.term - - def test_get_sample_type_cvs_1_1(self): - assert self.cv_service.get_sample_type_cvs() == [] - - sample_type = test_util.add_sample_type_cv(self.session) - db_sample_type = self.cv_service.get_sample_type_cvs()[0] - assert sample_type.term == db_sample_type.term - - def test_get_units_1_1(self): - assert self.cv_service.get_units() == [] - - unit = test_util.add_unit(self.session) - units = self.cv_service.get_units() - assert len(units) == 1 - assert unit.id == units[0].id - - ''' - - def test_get_unit_by_name(self): - with pytest.raises(sqlalchemy.orm.exc.NoResultFound): - self.cv_service.get_unit_by_name("Nothing") - - unit = test_util.add_unit(self.session) - db_unit = self.cv_service.get_unit_by_name(unit.name) - assert db_unit is not None - assert unit.id == db_unit.id - - def test_get_unit_by_id(self): - with pytest.raises(sqlalchemy.orm.exc.NoResultFound): - self.cv_service.get_unit_by_id(0) - - unit = test_util.add_unit(self.session) - db_unit = self.cv_service.get_unit_by_id(unit.id) - assert db_unit is not None - assert unit.name == db_unit.name - ''' - diff --git a/tests/test_odm1/test_odmservices/test_export_service_1_1.py b/tests/test_odm1/test_odmservices/test_export_service_1_1.py deleted file mode 100644 index c952d06..0000000 --- a/tests/test_odm1/test_odmservices/test_export_service_1_1.py +++ /dev/null @@ -1,36 +0,0 @@ -import os.path -from odm2api.ODM1_1_1.services import SeriesService, ExportService - -from tests import test_util1_1_1 as test_util - -import pytest - -@pytest.mark.skipif(True, - reason="ODM1.1 shim is out of date") -class TestExportService_1_1: - def setup(self): - self.connection_string = "sqlite:///:memory:" - self.series_service = SeriesService(self.connection_string, debug=False) - self.session = self.series_service._session_factory.get_session() - engine = self.series_service._session_factory.engine - test_util.build_db(engine) - self.series = test_util.add_series(self.session) - - self.export_service = ExportService(self.series_service) - - def test_export_series_data_1_1(self, tmpdir): - f = tmpdir.join("export.csv") - filename = f.dirname + f.basename - - self.export_service.export_series_data(self.series.id, filename, True,True,True,True,True,True,True) - - assert os.path.isfile(filename) == True - - def test_export_series_metadata_1_1(self, tmpdir): - f = tmpdir.join("export.xml") - filename = f.dirname + f.basename - - ids = [self.series.id] - self.export_service.export_series_metadata(ids, filename) - - assert os.path.isfile(filename) == True \ No newline at end of file diff --git a/tests/test_odm1/test_odmservices/test_series_service_1_1.py b/tests/test_odm1/test_odmservices/test_series_service_1_1.py deleted file mode 100644 index 2ee9a7e..0000000 --- a/tests/test_odm1/test_odmservices/test_series_service_1_1.py +++ /dev/null @@ -1,349 +0,0 @@ -from odm2api.ODM1_1_1.models import * -from odm2api.ODM1_1_1.services import SeriesService - -from tests import test_util1_1_1 as test_util -import pytest - -@pytest.mark.skipif(True, - reason="ODM1.1 shim is out of date") -class TestSeriesService_1_1: - def setup(self): - self.connection_string = "sqlite:///:memory:" - self.series_service = SeriesService(self.connection_string, debug=False) - self.session = self.series_service._session_factory.get_session() - engine = self.series_service._session_factory.engine - test_util.build_db(engine) - - def test_get_db_version_1_1(self): - version = test_util.add_version(self.session) - db_version = self.series_service.get_db_version() - assert version.version_number == db_version - - def test_get_all_sites_empty_1_1(self): - sites = self.series_service.get_used_sites() - #assert len(sites) == 0 - assert sites is None - - def test_create_qualifier_1_1(self): - qual = Qualifier() - qual.code = "ABC123" - qual.description = "This is a test" - self.series_service.create_qualifier_by_qual(qual) - - assert qual.id is not None - - def test_get_qualifiers_1_1(self): - assert self.series_service.get_all_qualifiers() == [] - - qual= self.series_service.create_qualifier("ABC123","This is a test") - - db_qual = self.series_service.get_all_qualifiers()[0] - assert qual.id == db_qual.id - - - def test_get_all_sites_1_1(self): - assert self.series_service.get_used_sites() is None - - site = test_util.add_site(self.session) - sites = self.series_service.get_used_sites() - assert sites is None - if isinstance(sites, list) and len(sites) > 0: - assert site.code == sites[0].code - - series = test_util.add_series(self.session) - site = series.site - sites = self.series_service.get_used_sites() - assert len(sites) == 1 - if isinstance(sites, list) and len(sites) > 0: - assert site.code == sites[0].code - - - def test_get_site_by_id_fail_1_1(self): - assert self.series_service.get_site_by_id(0) == None - - site = test_util.add_site(self.session) - db_site = self.series_service.get_site_by_id(10) - assert db_site == None - - def test_get_site_by_id_1_1(self): - site = test_util.add_site(self.session) - db_site = self.series_service.get_site_by_id(site.id) - assert db_site != None - assert site.code == db_site.code - - def test_get_all_variables_1_1(self): - assert self.series_service.get_all_variables() == [] - variable = test_util.add_variable(self.session) - variables = self.series_service.get_all_variables() - assert len(variables) == 1 - assert variable.code == variables[0].code - - def test_get_variable_by_id_1_1(self): - assert self.series_service.get_variable_by_id(10) == None - - variable = test_util.add_variable(self.session) - db_var = self.series_service.get_variable_by_id(variable.id) - - assert db_var != None - assert db_var.code == variable.code - - def test_get_variables_by_site_code_1_1(self): - assert self.series_service.get_variables_by_site_code('ABC123') == [] - - series = test_util.add_series(self.session) - variable = series.variable - - db_variables = self.series_service.get_variables_by_site_code(series.site_code) - assert db_variables != None - assert variable.code == db_variables[0].code - - def test_get_all_units_1_1(self): - assert self.series_service.get_all_units() == [] - - unit = test_util.add_unit(self.session) - units = self.series_service.get_all_units() - - assert len(units) == 1 - assert unit.name == units[0].name - - def test_get_unit_by_name_1_1(self): - assert self.series_service.get_unit_by_name("FAIL") == None - - unit = test_util.add_unit(self.session) - db_unit = self.series_service.get_unit_by_name(unit.name) - - assert unit.id == db_unit.id - - def test_get_unit_by_id_1_1(self): - assert self.series_service.get_unit_by_id(10) == None - - unit = test_util.add_unit(self.session) - db_unit = self.series_service.get_unit_by_id(unit.id) - - assert unit.name == db_unit.name - - def test_get_all_series_1_1(self): - assert self.series_service.get_all_series() == [] - - series = test_util.add_series(self.session) - all_series = self.series_service.get_all_series() - - assert all_series != [] - assert series.id == all_series[0].id - - def test_get_series_by_id_1_1(self): - assert self.series_service.get_series_by_id(10) == None - - series = test_util.add_series(self.session) - db_series = self.series_service.get_series_by_id(series.id) - - assert series.id == db_series.id - - def test_get_series_by_id_quint_1_1(self): - assert self.series_service.get_series_by_id_quint(10, 10, 10, 10, 10) == None - - series = test_util.add_series(self.session) - db_series = self.series_service.get_series_by_id_quint(series.site_id, series.variable_id, series.method_id, - series.source_id, series.quality_control_level_id) - - assert series.id == db_series.id - - def test_series_exists_1_1(self): - assert self.series_service.series_exists_quint(10, 10, 10, 10, 10) == False - - series = test_util.add_series(self.session) - site_id = series.site_id - var_id = series.variable_id - method_id = series.method_id - source_id = series.source_id - qcl_id = series.quality_control_level_id - - assert self.series_service.series_exists_quint(site_id, var_id, method_id, source_id, qcl_id) == True - - ## TODO Unittest save_series, save_as, save_as_existing - ''' - def test_save_series(self): - series = Series() - site = test_util.add_site(self.session) - variable = test_util.add_variable(self.session) - method = test_util.add_method(self.session) - source = test_util.add_source(self.session) - qcl = test_util.add_qcl(self.session) - - series.site_id = site.id - series.variable_id = variable.id - series.method_id = method.id - series.source_id = source.id - series.quality_control_level_id = qcl.id - - dvs = [] - for val in range(10): - dv = DataValue() - dv.data_value = val - dv.site_id = site.id - dv.variable_id = variable.id - dv.method_id = method.id - dv.source_id = source.id - dv.quality_control_level_id = qcl.id - dvs.append(dv) - - print series.variable_code - assert self.series_service.save_series(series) - assert self.series_service.series_exists(site.id, variable.id, method.id, source.id, qcl.id) - assert not self.series_service.save_series(series) - ''' - - def test_get_data_value_by_id(self): - assert self.series_service.get_data_value_by_id(10) == None - - data_values = test_util.add_series(self.session).data_values - dv = data_values[0] - db_dv = self.series_service.get_data_value_by_id(dv.id) - - assert dv.data_value == db_dv.data_value - - def test_get_qcl_by_id(self): - assert self.series_service.get_qcl_by_id(10) == None - - qcl = test_util.add_qcl(self.session) - db_qcl = self.series_service.get_qcl_by_id(qcl.id) - assert qcl.code == db_qcl.code - - def test_get_all_qcls(self): - assert self.series_service.get_all_qcls() == [] - - qcl = test_util.add_qcl(self.session) - all_qcls = self.series_service.get_all_qcls() - - assert len(all_qcls) == 1 - assert qcl.id == all_qcls[0].id - - def test_get_all_methods(self): - assert self.series_service.get_all_methods() == [] - - method = test_util.add_method(self.session) - all_methods = self.series_service.get_all_methods() - - assert len(all_methods) == 1 - assert method.id == all_methods[0].id - - def test_get_method_by_id(self): - assert self.series_service.get_method_by_id(10) == None - - method = test_util.add_method(self.session) - db_method = self.series_service.get_method_by_id(method.id) - - assert method.description == db_method.description - - def test_delete_dvs(self): - series = test_util.add_series(self.session) - dvs = series.data_values - - subset = dvs[:5] - self.series_service.delete_dvs([x.id for x in subset]) - assert self.series_service.get_data_value_by_id(subset[0].id) == None - series = self.series_service.get_series_by_id(series.id) # Reload - assert len(series.data_values) == 5 - - def test_update_dvs(self): - series = test_util.add_series(self.session) - dvs = series.data_values - - subset = dvs[:5] - for i in range(len(subset)): - subset[i].data_value = 100 - - self.series_service.update_dvs(subset) - series = self.series_service.get_series_by_id(series.id) - assert series.data_values[0].data_value == 100 - - def test_create_new_series(self): - site = test_util.add_site(self.session) - variable = test_util.add_variable(self.session) - method = test_util.add_method(self.session) - source = test_util.add_source(self.session) - qcl = test_util.add_qcl(self.session) - - dvs = [] - for val in range(10): - dv = DataValue() - dv.data_value = val - dv.site_id = site.id - dv.variable_id = variable.id - dv.method_id = method.id - dv.source_id = source.id - dv.quality_control_level_id = qcl.id - dvs.append(dv) - - series = self.series_service.create_new_series(dvs, site.id, variable.id, method.id, source.id, qcl.id) - assert series != None - assert len(series.data_values) == 10 - assert series.site_id == site.id - assert series.variable_id == variable.id - - def test_update_series(self): - series = test_util.add_series(self.session) - series.site_code = "NEW" - series.variable_code = "NEW" - - self.series_service.update_series(series) - - series = self.series_service.get_series_by_id(series.id) - assert series.site_code == "NEW" - assert series.variable_code == "NEW" - - def test_create_method(self): - description = "This tests creating a method" - link = "http://www.example.com" - method = self.series_service.create_method(description, link) - - assert method.id != None - assert method.description == description - assert method.link == link - - def test_create_variable(self): - unit = test_util.add_unit(self.session) - variable = self.series_service.create_variable("Code", "Name", "Speciation", unit.id, "SampleMedium", - "ValueType", True, # is_regular - 5.0, # time_support - unit.id, # time_unit_id - "DataType", "GeneralCategory", -999.0) # no_data_value - - assert variable.id != None - assert variable.code == "Code" - assert variable.variable_unit_id == unit.id - - def test_create_qcl(self): - qcl = self.series_service.create_qcl("Code", "Definition", "Explanation") - - assert qcl.id != None - assert qcl.code == "Code" - - def test_delete_series(self): - series = test_util.add_series(self.session) - assert self.series_service.get_series_by_id(series.id) != None - - self.series_service.delete_series(series) - assert self.series_service.get_series_by_id(series.id) == None - - def test_qcl_exists(self): - qcl = test_util.add_qcl(self.session) - assert self.series_service.qcl_exists(qcl) == True - - qcl.code = "00000" - qcl.definition = "A new definition" - assert self.series_service.qcl_exists(qcl) == False - - def test_method_exists(self): - method = test_util.add_method(self.session) - assert self.series_service.method_exists(method) == True - - method.description = "A new description" - assert self.series_service.method_exists(method) == False - - def test_variable_exists(self): - variable = test_util.add_variable(self.session) - assert self.series_service.variable_exists(variable) - variable.code = "00000" - variable.name = "A new name" - assert not self.series_service.variable_exists(variable) \ No newline at end of file diff --git a/tests/test_odm2/__init__.py b/tests/test_odm2/__init__.py index a24dbc6..223be85 100644 --- a/tests/test_odm2/__init__.py +++ b/tests/test_odm2/__init__.py @@ -1 +1,3 @@ +from __future__ import (absolute_import, division, print_function) + __author__ = 'stephanie' diff --git a/tests/test_odm2/data/empty.sql b/tests/test_odm2/data/empty.sql index 88f0131..9a5dd1a 100644 --- a/tests/test_odm2/data/empty.sql +++ b/tests/test_odm2/data/empty.sql @@ -278,6 +278,7 @@ BEGIN TRANSACTION;CREATE TABLE ActionAnnotations ( SamplingFeatureDescription VARCHAR (500) NULL, SamplingFeatureGeotypeCV VARCHAR (255) NULL, FeatureGeometry geometry NULL, + FeatureGeometryWKT VARCHAR (50) NULL, Elevation_m FLOAT NULL, ElevationDatumCV VARCHAR (255) NULL, FOREIGN KEY (ElevationDatumCV) REFERENCES CV_ElevationDatum (Name) diff --git a/tests/test_odm2/data/populated.sql b/tests/test_odm2/data/populated.sql index 7377897..84a1e23 100644 --- a/tests/test_odm2/data/populated.sql +++ b/tests/test_odm2/data/populated.sql @@ -330,6 +330,7 @@ CREATE TABLE SamplingFeatures ( SamplingFeatureDescription VARCHAR (500) NULL, SamplingFeatureGeotypeCV VARCHAR (255) NULL, FeatureGeometry geometry NULL, + FeatureGeometryWKT VARCHAR(50) NULL, Elevation_m FLOAT NULL, ElevationDatumCV VARCHAR (255) NULL, FOREIGN KEY (ElevationDatumCV) REFERENCES CV_ElevationDatum (Name) @@ -339,8 +340,8 @@ CREATE TABLE SamplingFeatures ( FOREIGN KEY (SamplingFeatureTypeCV) REFERENCES CV_SamplingFeatureType (Name) ON UPDATE NO ACTION ON DELETE NO ACTION ); -INSERT INTO "SamplingFeatures" VALUES(1,'1fe94bae-4524-11e5-b966-7831c1d1cf54','Site','LR_WaterLab_AA','Logan River at the Utah Water Research Laboratory west bridge',NULL,'Point','POINT (41.739034 -111.795742)',1414.0,'EGM96'); -INSERT INTO "SamplingFeatures" VALUES(2,'19b067c7-6a74-475d-8b7f-826b133cd91e','outlet','logan_river_outlet','logan watershed outlet','the outlet of the logan river watershed','point1d',X'0001000000006BD3D85E0BF25B40CF84268925DF44406BD3D85E0BF25B40CF84268925DF44407C010000006BD3D85E0BF25B40CF84268925DF4440FE',4680.0,'epsg:5702'); +INSERT INTO "SamplingFeatures" VALUES(1,'1fe94bae-4524-11e5-b966-7831c1d1cf54','Site','LR_WaterLab_AA','Logan River at the Utah Water Research Laboratory west bridge',NULL,'Point','POINT (41.739034 -111.795742)',NULL, 1414.0,'EGM96'); +INSERT INTO "SamplingFeatures" VALUES(2,'19b067c7-6a74-475d-8b7f-826b133cd91e','outlet','logan_river_outlet','logan watershed outlet','the outlet of the logan river watershed','point1d',X'0001000000006BD3D85E0BF25B40CF84268925DF44406BD3D85E0BF25B40CF84268925DF44407C010000006BD3D85E0BF25B40CF84268925DF4440FE',NULL, 4680.0,'epsg:5702'); CREATE TABLE TaxonomicClassifiers ( TaxonomicClassifierID INTEGER NOT NULL PRIMARY KEY, TaxonomicClassifierTypeCV VARCHAR (255) NOT NULL, @@ -15947,7 +15948,7 @@ CREATE TABLE Models ( INSERT INTO "Models" VALUES(1,'swat','soil and water assessment tool','The Soil and Water Assessment Tool (SWAT) is a public domain Model jointly developed by USDA Agricultural Research Service (USDA-ARS) and Texas A&M AgriLife Research, part of The Texas A&M University System. SWAT is a small watershed to river basin-scale Model to simulate the quality and quantity of surface and ground water and predict the environmental impact of land use, land management practices, and climate change.',NULL,NULL); INSERT INTO "Models" VALUES(2,'swmm','storm water management model','SWMM is a dynamic hydrology-hydraulic water quality simulation model. It is used for single event or long-term (continuous) simulation of runoff quantity and quality from primarily urban areas. The runoff component operates on a collection of sub catchment areas that receive precipitation and generate runoff and pollutant loads. The routing portion transports this runoff through a system of pipes, channels, storage/treatment devices, pumps, and regulators.','5.1.010','http://www.epa.gov/water-research/storm-water-management-model-swmm'); CREATE TABLE RelatedModels ( - RelationID INTEGER NOT NULL PRIMARY KEY, + RelatedID INTEGER NOT NULL PRIMARY KEY, ModelID INTEGER NOT NULL, RelationshipTypeCV VARCHAR (255) NOT NULL, RelatedModelID INTEGER NOT NULL, diff --git a/tests/test_odm2/test_createservice.py b/tests/test_odm2/test_createservice.py index 87275a4..cff0466 100644 --- a/tests/test_odm2/test_createservice.py +++ b/tests/test_odm2/test_createservice.py @@ -1,268 +1,310 @@ -import pytest +from __future__ import (absolute_import, division, print_function) + import datetime -from os.path import * +import uuid +from os.path import abspath, dirname, join + from odm2api.ODM2 import models -from odm2api.ODMconnection import dbconnection from odm2api.ODM2.services.createService import CreateODM2 +from odm2api.ODMconnection import dbconnection + +import pytest # run this test from the root directory using: # python -m pytest tests/test_odm2/test_createservice.py -globals = {} +globals_vars = {} + class TestCreateService: - @pytest.fixture(scope="class", autouse=True) + @pytest.fixture(scope='class', autouse=True) def build_db(self): """ Builds an empty sqlite (in-memory) database for testing :return: None + """ # path to the ddl script for building the database - ddlpath= abspath(join(dirname(__file__), 'data/empty.sql')) + ddlpath = abspath(join(dirname(__file__), 'data/empty.sql')) # create and empty sqlite database for testing db = dbconnection.createConnection('sqlite', ':memory:') # read the ddl script and remove the first (BEGIN TRANSACTION) and last (COMMIT) lines ddl = open(ddlpath, 'r').read() - ddl = ddl.replace('BEGIN TRANSACTION;','') - ddl = ddl.replace('COMMIT;','') + ddl = ddl.replace('BEGIN TRANSACTION;', '') + ddl = ddl.replace('COMMIT;', '') # execute each statement to build the odm2 database for line in ddl.split(');')[:-1]: try: db.engine.execute(line + ');') - except Exception, e: - print e + except Exception as e: + print(e) self.write = CreateODM2(db) - self.engine= db.engine + self.engine = db.engine - globals['write'] = self.write - globals['engine'] = self.engine - globals['db'] = db - # return self.write, self.engine + globals_vars['write'] = self.write + globals_vars['engine'] = self.engine + globals_vars['db'] = db def setup(self): - - self.writer = globals['write'] - self.engine = globals['engine'] - self.db = globals['db'] + self.writer = globals_vars['write'] + self.engine = globals_vars['engine'] + self.db = globals_vars['db'] def test_createVariable(self): - # assert that there are no variables in the database res = self.engine.execute('SELECT * from Variables') assert(len(res.fetchall()) == 0) - # create a new variable code = 'MyVar' name = 'My Test Variable' vType = 'Hydrology' nodv = -9999 - speciation="mg/L as PO4" - definition="This is a test variable" - self.writer.createVariable(code = code,name = name,vType = vType,nodv =nodv,speciation=None,definition=None) - - # assert that this dataset has been successfully inserted - res = self.engine.execute('SELECT * from Variables WHERE VariableCode = "MyVar" ORDER BY VariableID DESC').first() + speciation = 'mg/L as PO4' + definition = 'This is a test variable' + v = models.Variables( + VariableCode=code, + VariableNameCV=name, + VariableTypeCV=vType, + NoDataValue=nodv, + SpeciationCV=None, + VariableDefinition=None + ) + val = self.writer.createVariable(v) + res = self.engine.execute( + 'SELECT * from Variables WHERE VariableCode = "MyVar" ORDER BY VariableID DESC' + ).first() assert(res is not None) - assert(res[1] == vType ) # vType - assert(res[2] == code ) # code - assert(res[3] == name ) # name - assert(res[4] == None) # definition - assert(res[5] == None) # speciation - assert(res[6] == nodv ) # nodata - - self.writer.createVariable(code = code, name = name, vType = vType, nodv =nodv, speciation=speciation,definition=None) - + assert(res[0] == val.VariableID) + assert(res[1] == vType) # vType + assert(res[2] == code) # code + assert(res[3] == name) # name + assert(res[4] is None) # definition + assert(res[5] is None) # speciation + assert(res[6] == nodv) # nodata + + v = models.Variables( + VariableCode=code, + VariableNameCV=name, + VariableTypeCV=vType, + NoDataValue=nodv, + SpeciationCV=speciation, + VariableDefinition=None + ) + val = self.writer.createVariable(v) # assert that this dataset has been successfully inserted - res = self.engine.execute('SELECT * from Variables WHERE VariableCode = "MyVar" ORDER BY VariableID DESC').first() + res = self.engine.execute( + 'SELECT * from Variables WHERE VariableCode = "MyVar" ORDER BY VariableID DESC' + ).first() assert(res is not None) - assert(res[1] == vType ) # vType - assert(res[2] == code ) # code - assert(res[3] == name ) # name - assert(res[4] == None) # definition - assert(res[5] == speciation) # speciation - assert(res[6] == nodv ) # nodata - - - self.writer.createVariable(code = code,name = name,vType = vType,nodv =nodv,speciation=None,definition=definition) + assert(res[0] == val.VariableID) + assert(res[1] == vType) # vType + assert(res[2] == code) # code + assert(res[3] == name) # name + assert(res[4] is None) # definition + assert(res[5] == speciation) # speciation + assert(res[6] == nodv) # nodata + + v = models.Variables( + VariableCode=code, + VariableNameCV=name, + VariableTypeCV=vType, + NoDataValue=nodv, + SpeciationCV=None, + VariableDefinition=definition + ) + val = self.writer.createVariable(v) # assert that this dataset has been successfully inserted - res = self.engine.execute('SELECT * from Variables WHERE VariableCode = "MyVar" ORDER BY VariableID DESC').first() + res = self.engine.execute( + 'SELECT * from Variables WHERE VariableCode = "MyVar" ORDER BY VariableID DESC' + ).first() assert(res is not None) - assert(res[1] == vType ) # vType - assert(res[2] == code ) # code - assert(res[3] == name ) # name - assert(res[4] == definition) # definition - assert(res[5] == None) # speciation - assert(res[6] == nodv ) # nodata - - - self.writer.createVariable(code = code,name = name,vType = vType,nodv =nodv,speciation=speciation,definition=definition) - - # assert that this dataset has been successfully inserted - res = self.engine.execute('SELECT * from Variables WHERE VariableCode = "MyVar" ORDER BY VariableID DESC').first() + assert(res[0] == val.VariableID) + assert(res[1] == vType) # vType + assert(res[2] == code) # code + assert(res[3] == name) # name + assert(res[4] == definition) # definition + assert(res[5] is None) # speciation + assert(res[6] == nodv) # nodata + + v = models.Variables( + VariableCode=code, + VariableNameCV=name, + VariableTypeCV=vType, + NoDataValue=nodv, + SpeciationCV=speciation, + VariableDefinition=definition + ) + + val = self.writer.createVariable(v) + + res = self.engine.execute( + 'SELECT * from Variables WHERE VariableCode = "MyVar" ORDER BY VariableID DESC' + ).first() assert(res is not None) - assert(res[1] == vType ) # vType - assert(res[2] == code ) # code - assert(res[3] == name ) # name - assert(res[4] == definition) # definition - assert(res[5] == speciation) # speciation - assert(res[6] == nodv ) # nodata - - - + assert(res[0] == val.VariableID) + assert(res[1] == vType) # vType + assert(res[2] == code) # code + assert(res[3] == name) # name + assert(res[4] == definition) # definition + assert(res[5] == speciation) # speciation + assert(res[6] == nodv) # nodata + + @pytest.mark.skipif(True, reason='implement') def test_createMethod(self): pass + @pytest.mark.skipif(True, reason='implement') def test_createProcessingLevel(self): - pass + pass + @pytest.mark.skipif(True, reason='implement') def test_createSamplingFeature(self): pass + @pytest.mark.skipif(True, reason='implement') def test_createUnit(self): pass - + + @pytest.mark.skipif(True, reason='implement') def test_createOrganization(self): - pass + pass + @pytest.mark.skipif(True, reason='implement') def test_createPerson(self): pass - def test_createAffiliation(self): + @pytest.mark.skipif(True, reason='implement') + def test_createAffiliation(self): pass def test_createDataset(self): - type = "Generic" - code = "MyNewDataset" - title= "Just a test dataset" - desc = "this record represents a test dataset" + dataset_type_cv = 'Generic' + code = 'MyNewDataset' + title = 'Just a test dataset' + desc = 'this record represents a test dataset' - # assert that there are no datasets in the database res = self.engine.execute('SELECT * from DataSets') assert(len(res.fetchall()) == 0) # create a new dataset - dataset = self.writer.createDataset(dstype=type, - dscode=code, - dstitle=title, - dsabstract=desc) + d = models.DataSets( + DataSetTypeCV=dataset_type_cv, + DataSetCode=code, + DataSetTitle=title, + DataSetAbstract=desc, + DataSetUUID=uuid.uuid4().hex + ) + dataset = self.writer.createDataset(d) + assert(dataset == d) + assert (dataset.DataSetID == 1) # assert that this dataset has been successfully inserted - res = self.engine.execute('SELECT * from DataSets') - assert(len(res.fetchall()) == 1) + res = self.engine.execute('SELECT * from DataSets').fetchall() + assert(len(res) == 1) + assert(res[0][0] == dataset.DataSetID) + @pytest.mark.skipif(True, reason='implement') def test_createDatasetResults(self): pass - + + @pytest.mark.skipif(True, reason='implement') def test_createAction(self): pass - def test_createActionBy(self): + @pytest.mark.skipif(True, reason='implement') + def test_createActionBy(self): pass - + + @pytest.mark.skipif(True, reason='implement') def test_createFeatureAction(self): pass - def test_createResult(self): - - # assert that there are no results - res = self.engine.execute('SELECT * FROM Results') - assert(len(res.fetchall()) == 0) - - # create a result record - self.writer.createResult(featureactionid = 1, - variableid = 1, - unitid = 1, - processinglevelid = 1, - valuecount = 0, - sampledmedium = 'unknown', - resulttypecv = 'time series', - taxonomicclass=None, resultdatetime=None, resultdatetimeutcoffset=None, - validdatetime=None, validdatetimeutcoffset=None, statuscv=None) - - - # assert that there are results - res = self.engine.execute('SELECT * FROM Results') - assert(len(res.fetchall()) == 1) - def test_createTimeSeriesResult(self): - # assert that there are no time series results in the database res = self.engine.execute('SELECT * FROM TimeSeriesResults').first() assert(res is None) - - # create a result record if it doesnt exist (required to test foriegn key relationship) - result = self.engine.execute('SELECT * FROM Results').first() - if result is None: - # create a basic result record - self.writer.createResult(featureactionid = 1,variableid = 1,unitid = 1,processinglevelid = 1, - valuecount = 0,sampledmedium = 'unknown',resulttypecv = 'time series') - result = self.engine.execute('SELECT * FROM Results').first() - assert(result is not None) - # create most basic time series result record possible - tsr = self.writer.createTimeSeriesResult(result=result, aggregationstatistic='unknown') - - # assert that this basic tsr exists in the datbase - res = self.engine.execute('SELECT * FROM TimeSeriesResults').first() - assert(res is not None) - + r = models.TimeSeriesResults( + FeatureActionID=1, + VariableID=1, + UnitsID=1, + ProcessingLevelID=1, + ValueCount=0, + SampledMediumCV='unknown', + ResultTypeCV='time series', + ResultUUID=str(uuid.uuid4()), + AggregationStatisticCV='unknown' + ) + newres = self.writer.createResult(r) + # assert that this basic tsr exists in the database + tsr = self.engine.execute('SELECT * FROM TimeSeriesResults').first() + assert(tsr is not None) + + assert (newres == r) + result = self.engine.execute('SELECT * FROM Results').first() + assert(result is not None) + assert(newres.ResultID == 1) + assert(result[0] == newres.ResultID) + @pytest.mark.skipif(True, reason='implement') def test_createTimeSeriesResultValues(self): pass - - def test_createSite(self): + @pytest.mark.skipif(True, reason='implement') + def test_createSite(self): pass - - def test_createSpatialReference(self): + @pytest.mark.skipif(True, reason='implement') + def test_createSpatialReference(self): pass - def test_createDeploymentAction(self): + @pytest.mark.skipif(True, reason='implement') + def test_createDeploymentAction(self): pass - + @pytest.mark.skipif(True, reason='implement') def test_createModel(self): pass - + @pytest.mark.skipif(True, reason='implement') def test_createRelatedModel(self): pass - - - def test_createSimulation(self): + def test_createSimulation(self): # todo: insert should fail if unitID or actionID do not exist - # assert that there are no datasets in the database res = self.engine.execute('SELECT * from Simulations') assert(len(res.fetchall()) == 0) # create a new simulation - st = datetime.datetime(2016,1,1) - et = datetime.datetime(2016,1,25) - dataset = self.writer.createSimulation( actionid = 1, - modelID=1, - simulationName= 'MySimulation', - simulationDescription = 'My simulation description', - simulationStartDateTime = st, - simulationStartOffset = 6, - simulationEndDateTime = et, - simulationEndOffset = 6, - timeStepValue = 1, - timeStepUnitID = 1, - inputDatasetID=None) - + st = datetime.datetime(2016, 1, 1) + et = datetime.datetime(2016, 1, 25) + s = models.Simulations( + ActionID=1, + SimulationName='MySimulation', + SimulationDescription='My simulation description', + SimulationStartDateTime=st, + SimulationStartDateTimeUTCOffset=6, + SimulationEndDateTime=et, + SimulationEndDateTimeUTCOffset=6, + TimeStepValue=1, + TimeStepUnitsID=1, + InputDataSetID=None, + ModelID=1 + ) + sim = self.writer.createSimulation(s) + assert (s == sim) + assert (s.SimulationID == 1) # assert that this record has been successfully inserted - res = self.engine.execute('SELECT * from Simulations') - assert(len(res.fetchall()) == 1) - + res = self.engine.execute('SELECT * from Simulations').fetchall() + assert(len(res) == 1) + assert(res[0][0] == s.SimulationID) diff --git a/tests/test_odm2/test_model.py b/tests/test_odm2/test_model.py index 3ce7e3d..82c6283 100644 --- a/tests/test_odm2/test_model.py +++ b/tests/test_odm2/test_model.py @@ -1,68 +1,42 @@ -__author__ = 'stephanie' -# run with 'py.test -s test_example.py' -from odm2api.ODMconnection import dbconnection -from odm2api.ODM2.models import * -from .. import test_connection as testConnection +from __future__ import (absolute_import, division, print_function) + +from odm2api.ODM2.models import (CVElevationDatum, CVSamplingFeatureGeoType, + CVSamplingFeatureType, SamplingFeatures) + import pytest -# class Connection: -# def __init__(self, request): -# #session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm') -# db = request.param -# session_factory = dbconnection.createConnection(db[0],db[1],db[2],db[3],) -# self.session = session_factory.getSession() +from .. import test_connection as testConnection + +__author__ = 'stephanie' -# assumes that pytest is being run from ODM2PythonAPI directory dbs = testConnection.dbs_readonly -# dbs = [ -# # ['mysql', 'localhost', 'odm2', 'ODM', 'odm'], -# # ["sqlite", "./tests/spatialite/odm2_test.sqlite",None, None] -# ["sqlite", "../odm2_test.sqlite",None, None, None] -# ] -# -# params=["sqlite+pysqlite:///../../ODM2PythonAPI/tests/spatialite/odm2_test.sqlite", "mail.python.org"]) -@pytest.fixture(scope="session", params = dbs) + +@pytest.fixture(scope='session', params=dbs) def setup(request): return testConnection.Connection(request) - # #session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm') - # db = request.param - # session_factory = dbconnection.createConnection(db[0],db[1],db[2],db[3],) - # self.session = session_factory.getSession() -############ -# Fixtures # -############ -#class TestODM2: -# @pytest.fixture(autouse=True) +# Fixtures def test_cvelevationdatum(setup): - q= setup.session.query(CVElevationDatum) - results= q.all() - #print results + q = setup.session.query(CVElevationDatum) + results = q.all() assert len(results) > 0 + def test_cvsamplingfeatuergeotype(setup): - q=setup.session.query(CVSamplingFeatureGeoType) + q = setup.session.query(CVSamplingFeatureGeoType) results = q.all() - #print results assert len(results) > 0 + def test_cvsamplingfeaturetype(setup): q = setup.session.query(CVSamplingFeatureType) results = q.all() - #print results assert len(results) > 0 + def test_sampling_feature(setup): q = setup.session.query(SamplingFeatures) results = q.all() - ''' - for r in results: - print r - print r.SamplingFeatureGeotypeCV - print r.FeatureGeometry - #print results - ''' assert len(results) > 0 - diff --git a/tests/test_odm2/test_odm2.py b/tests/test_odm2/test_odm2.py new file mode 100644 index 0000000..a50f470 --- /dev/null +++ b/tests/test_odm2/test_odm2.py @@ -0,0 +1,360 @@ +from __future__ import (absolute_import, division, print_function) + +from odm2api.ODM2.models import Methods, Models, People, ProcessingLevels, RelatedModels, Variables +from odm2api.ODM2.services.createService import CreateODM2 +from odm2api.ODM2.services.deleteService import DeleteODM2 +from odm2api.ODM2.services.readService import ReadODM2 +from odm2api.ODM2.services.updateService import UpdateODM2 +from odm2api.ODMconnection import dbconnection + +import pytest + +from tests import test_connection as testConnection + + +__author__ = ['tony castronova', 'david valentine'] + + +xfail = pytest.mark.xfail +skipif = xfail = pytest.mark.skipif + + +dbs = testConnection.dbs_test + + +class odmConnection(): + pass + + +@pytest.fixture(scope='function', params=dbs) +def setup(request): + # build an empty database for testing + # conn = dbconnection.createConnection('sqlite', ':memory:') + db = request.param + print('dbtype', db[0], db[1]) + session_factory = dbconnection.createConnection(db[1], db[2], db[3], db[4], db[5], echo=False) + assert session_factory is not None, ('failed to create a session for ', db[0], db[1]) + assert session_factory.engine is not None, ('failed: session has no engine ', db[0], db[1]) + # dbconnection._setSchema(conn.engine) + dbConn = odmConnection + # build connectors for read, write, update, and delete operations + dbConn.odmread = ReadODM2(session_factory) + dbConn.odmcreate = CreateODM2(session_factory) + dbConn.odmupdate = UpdateODM2(session_factory) + dbConn.odmdelete = DeleteODM2(session_factory) + s = session_factory.getSession() + if (db[2] == ':memory:'): + build = open('./tests/schemas/sqlite/ODM2_for_SQLite.sql').read() + for line in build.split(';\n'): + s.execute(line) + s.flush() + print('database initialization completed successfully') + + def fin(): + print('teardown odm2 test connection') + del dbConn.odmread + del dbConn.odmcreate + del dbConn.odmupdate + del dbConn.odmdelete + session_factory.engine.dispose() + session_factory.test_engine.dispose() + s.invalidate() + + request.addfinalizer(fin) + + return dbConn + + +@pytest.mark.skipif(True, reason='Enable for testing: CreateService Session closes on failed create #52') +def test_SessionNotFailed(setup): + setup.odmcreate.createPerson( + firstName='tony', + lastName='castronova', + middleName='michael' + ) + + with pytest.raises(Exception) as excinfo: + # this one should fail due to a not null constraint + setup.odmcreate.createPerson(firstName=None, + lastName='castronova', + middleName='michael') + + assert 'NULL' in str(excinfo.value) + + # now add again + setup.odmcreate.createPerson(firstName='tony', + lastName='castronova', + middleName=None) + + setup.odmcreate.createPerson( + firstName='john', + lastName='doe' + ) + + people = setup.odmread.getPeople() + assert len(people) == 3, 'People should have been 3' + + +def test_createPerson(setup): + + # create some people + p1 = People(PersonFirstName='tony', PersonLastName='castronova', PersonMiddleName='Michael') + p2 = People(PersonFirstName='tony', PersonLastName='castronova') + p3 = People(PersonFirstName='john', PersonLastName='doe') + setup.odmcreate.createPerson(p1) + setup.odmcreate.createPerson(p2) + setup.odmcreate.createPerson(p3) + people = setup.odmread.getPeople() + assert len(people) == 3, 'People should have been 3' + + +def test_personFail(setup): + with pytest.raises(Exception) as excinfo: + # this one should fail due to a not null constraint + p1 = People(PersonFirstName=None, PersonLastName='doe', PersonMiddleName='john') + setup.odmcreate.createPerson(p1) + assert 'null' in str(excinfo.value).lower() + + +def test_createVariable(setup): + v1 = Variables(VariableCode='Phos_TOT', + VariableNameCV='Phosphorus, total dissolved', + VariableTypeCV='Hydrology', + NoDataValue=-999, + SpeciationCV=None, + VariableDefinition=None) + v2 = Variables(VariableCode='Phos_TOT2', + VariableNameCV='Phosphorus, total dissolved', + VariableTypeCV='Hydrology', + NoDataValue=-999, + SpeciationCV='mg/L', + VariableDefinition=None) + v3 = Variables(VariableCode='Phos_TOT3', + VariableNameCV='Phosphorus, total dissolved', + VariableTypeCV='Hydrology', + NoDataValue=-999, + SpeciationCV=None, + VariableDefinition='some definition') + # create some variables + setup.odmcreate.createVariable(v1) + setup.odmcreate.createVariable(v2) + setup.odmcreate.createVariable(v3) + + variables = setup.odmread.getVariables() + print(variables) + assert len(variables) == 3 + + with pytest.raises(Exception) as excinfo: + # insert duplicate + setup.odmcreate.createVariable( + Variables( + VariableCode='Phos_TOT', + VariableNameCV='Phosphorus, total dissolved', + VariableTypeCV='Hydrology', + NoDataValue=-999, + SpeciationCV=None, + VariableDefinition=None + ) + ) + + assert 'unique' in str(excinfo.value).lower() + + +def test_createMethod(setup): + m1 = Methods(MethodCode='mycode', + MethodName='my test method', + MethodTypeCV='Unknown', + MethodDescription='method description', + MethodLink=None, + OrganizationID=None) + m2 = Methods(MethodCode='mycode2', + MethodName='my test method', + MethodTypeCV='Unknown', + MethodDescription='method description', + MethodLink=None, + OrganizationID=1) + m3 = Methods(MethodCode='mycode3', + MethodName='my test method', + MethodTypeCV='Unknown', + MethodDescription=None, + MethodLink=None, + OrganizationID=None) + setup.odmcreate.createMethod(m1) + setup.odmcreate.createMethod(m2) + setup.odmcreate.createMethod(m3) + methods = setup.odmread.getMethods() + assert len(methods) == 3 + + +def test_ProcessingLevel(setup): + pl = ProcessingLevels(ProcessingLevelCode='testlevel', + Definition='this is a test processing level', + Explanation=None) + setup.odmcreate.createProcessingLevel(pl) + res = setup.odmread.getProcessingLevels() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createSamplingFeature(setup): + res = setup.odmread.getSamplingFeatures() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createUnit(setup): + res = setup.odmread.getUnits() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createOrganization(setup): + res = setup.odmread.getOrganizations() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createAffiliation(setup): + res = setup.odmread.getAffiliationsByPerson() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createDataset(setup): + res = setup.odmread.getDataSets() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createDatasetResults(setup): + res = setup.odmread.getProcessingLevels() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createAction(setup): + # todo: this function is missing + # res = self.odmread.getActions() + assert 0 == 1 + + +@skipif(True, reason='Needs data') +def test_createActionBy(setup): + # todo; this function is missing + # res = self.odmread.getActionsBy() + assert 0 == 1 + + +@skipif(True, reason='Needs data') +def test_createFeatureAction(setup): + # todo: this function is missing + # res = self.odmread.getFeatureActions() + assert 0 == 1 + + +@skipif(True, reason='Needs data') +def test_createResult(setup): + res = setup.odmread.getResults() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createTimeSeriesResult(setup): + res = setup.odmread.getTimeSeriesResults() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createTimeSeriesResultValues(setup): + res = setup.odmread.getTimeSeriesResultValues() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createSite(setup): + res = setup.odmread.getAllSites() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createSpatialReference(setup): + res = setup.odmread.getSpatialReferenceByCode() + assert len(res) == 1 + + +@skipif(True, reason='Needs data') +def test_createDeploymentAction(setup): + res = setup.odmread.getAllDeploymentAction() + assert len(res) == 1 + + +def test_createModel(setup): + mod1 = Models(ModelCode='converter', + ModelName='mymodel', + ModelDescription='my test converter') + mod2 = Models(ModelCode='model2', + ModelName='mymodel', + ModelDescription=None) + mod3 = Models(ModelCode='converter', + ModelName='mymodel2', + ModelDescription='my test model2') + # create converter (expected: record inserted) + setup.odmcreate.createModel(mod1) + + # create with no description (expected: record inserted) + setup.odmcreate.createModel(mod2) + + res = setup.odmread.getModels() + assert len(res) == 2 + + res = setup.odmread.getModels(codes=['converter']) + assert res is not None + assert res[0].ModelCode == 'converter' + + with pytest.raises(Exception) as excinfo: + # create converter with duplicate code (expected: fail to insert record) + setup.odmcreate.createModel(mod3) + assert 'unique' in str(excinfo.value).lower() + + +def test_createRelatedModel(setup): + # create a relationship type + setup.odmcreate.getSession().execute( + 'insert into cv_relationshiptype values ("coupled", "coupled converter", "models that have been coupled together", "modeling", NULL)' # noqa + ) + mod1 = Models(ModelCode='converter', + ModelName='mymodel', + ModelDescription='my test converter') + mod2 = Models(ModelCode='model2', + ModelName='mymodel', + ModelDescription='my test model2') + # create converter (expected: record inserted) + m1 = setup.odmcreate.createModel(mod1) + # create converter (expected: record inserted) + m2 = setup.odmcreate.createModel(mod2) + + rm = RelatedModels(ModelID=m1.ModelID, + RelatedModelID=m2.ModelID, + RelationshipTypeCV='Is part of') + # create related records + setup.odmcreate.createRelatedModel(rm) + + m1r = setup.odmread.getModels(codes=['converter']) + assert m1r is not None + assert m1r[0].ModelCode == 'converter' + + m2r = setup.odmread.getModels(codes=['model2']) + assert m2r is not None + assert m2r[0].ModelCode == 'model2' + + m1rel = setup.odmread.getRelatedModels(code='converter') + assert len(m1rel) == 1 + + m2rel = setup.odmread.getRelatedModels(code='model2') + assert len(m2rel) == 0 + + +@skipif(True, reason='Needs data') +def test_createSimulation(setup): + res = setup.odmread.getAllSimulations() + assert len(res) == 1 diff --git a/tests/test_odm2/test_readservice.py b/tests/test_odm2/test_readservice.py index 2029635..6ea9154 100644 --- a/tests/test_odm2/test_readservice.py +++ b/tests/test_odm2/test_readservice.py @@ -1,87 +1,98 @@ -import pytest -import datetime -from os.path import * +from __future__ import (absolute_import, division, print_function) + +from os.path import abspath, dirname, join + from odm2api.ODM2 import models -from odm2api.ODMconnection import dbconnection from odm2api.ODM2.services.readService import ReadODM2 -from sqlalchemy.orm import class_mapper +from odm2api.ODMconnection import dbconnection + +import pytest + import sqlalchemy +from sqlalchemy.orm import class_mapper -# run this test from the root directory using: -# python -m pytest tests/test_odm2/test_readservice.py -globals = {} +globals_vars = {} def rawSql2Alchemy(rawsqlresult, sqlalchemyClass): """ - converts the results of a raw sql select query into SqlAlchemy Model Object + converts the results of a raw sql select query into SqlAlchemy converter Object :param rawsqlresult: array of values, sql select results - :param sqlalchemyModelObj: model object to convert into - :return: populated model object - """ + :param sqlalchemyModelObj: converter object to convert into + :return: populated converter object - map = {} - class_attributes = [prop.key for prop in class_mapper(sqlalchemyClass).iterate_properties - if isinstance(prop, sqlalchemy.orm.ColumnProperty)] + """ + m = {} + class_attributes = [ + prop.key for prop in class_mapper(sqlalchemyClass).iterate_properties + if isinstance(prop, sqlalchemy.orm.ColumnProperty) + ] for i in range(len(class_attributes)): - map[class_attributes[i]] = rawsqlresult[i] + m[class_attributes[i]] = rawsqlresult[i] modelObj = sqlalchemyClass() - modelObj.__dict__ = map + modelObj.__dict__ = m return modelObj - class TestReadService: - - @pytest.fixture(scope="class", autouse=True) + @pytest.fixture(scope='class', autouse=True) def build_db(self): """ Builds a populated sqlite (in-memory) database for testing :return: None - """ + """ # path to the ddl script for building the database - ddlpath= abspath(join(dirname(__file__), 'data/populated.sql')) + ddlpath = abspath(join(dirname(__file__), 'data/populated.sql')) # create and empty sqlite database for testing db = dbconnection.createConnection('sqlite', ':memory:') # read the ddl script and remove the first (BEGIN TRANSACTION) and last (COMMIT) lines ddl = open(ddlpath, 'r').read() - ddl = ddl.replace('BEGIN TRANSACTION;','') - ddl = ddl.replace('COMMIT;','') + ddl = ddl.replace('BEGIN TRANSACTION;', '') + ddl = ddl.replace('COMMIT;', '') # execute each statement to build the odm2 database for line in ddl.split(');')[:-1]: try: db.engine.execute(line + ');') - except Exception, e: - print e + except Exception as e: + print(e) self.reader = ReadODM2(db) - self.engine= db.engine + self.engine = db.engine - globals['reader'] = self.reader - globals['engine'] = self.engine - globals['db'] = db - # return self.write, self.engine + globals_vars['reader'] = self.reader + globals_vars['engine'] = self.engine + globals_vars['db'] = db def setup(self): - - self.reader = globals['reader'] - self.engine = globals['engine'] - self.db = globals['db'] + self.reader = globals_vars['reader'] + self.engine = globals_vars['engine'] + self.db = globals_vars['db'] +# Sampling Features + def test_getAllSamplingFeatures(self): + # get all models from the database + res = self.engine.execute('SELECT * FROM SamplingFeatures').fetchall() + # get all simulations using the api + resapi = self.reader.getSamplingFeatures() + assert len(res) == len(resapi) + def test_getSamplingFeatureByID(self): + # get all models from the database + res = self.engine.execute('SELECT * FROM SamplingFeatures').fetchone() + sfid = res[0] + # get all simulations using the api + resapi = self.reader.getSamplingFeatures(ids=[sfid]) + assert resapi is not None -# ################################################################################ # Models -# ################################################################################ - """ TABLE Models ModelID INTEGER NOT NULL PRIMARY KEY, @@ -93,32 +104,22 @@ def setup(self): """ def test_getAllModels(self): - # get all models from the database res = self.engine.execute('SELECT * FROM Models').fetchall() - # get all simulations using the api - resapi = self.reader.getAllModels() - + resapi = self.reader.getModels() assert len(res) == len(resapi) def test_getModelByCode(self): - - # get a model from the database + # get a converter from the database res = self.engine.execute('SELECT * FROM Models').fetchone() modelCode = res[1] - - - # get the model using the api - resapi = self.reader.getModelByCode(modelcode=modelCode) - + # get the converter using the api + resapi = self.reader.getModels(codes=[modelCode]) assert resapi is not None -# ################################################################################ # RelatedModels -# ################################################################################ - """ TABLE RelatedModels ( RelatedID INTEGER NOT NULL PRIMARY KEY, @@ -132,36 +133,66 @@ def test_getModelByCode(self): """ def test_getRelatedModelsByID(self): - # get related models by id using the api - resapi = self.reader.getRelatedModelsByID(2) - + resapi = self.reader.getRelatedModels(id=1) assert resapi is not None - assert resapi[0].ModelObj.ModelCode == 'swat' + assert resapi[0].ModelCode == 'swat' def test_getRelatedModelsByCode(self): - # get related models by id using the api - resapi = self.reader.getRelatedModelsByCode('swmm') - + resapi = self.reader.getRelatedModels(code='swat') assert resapi is not None assert len(resapi) > 0 - assert resapi[0].ModelObj.ModelCode == 'swat' + print(resapi[0].ModelCode) + assert resapi[0].ModelCode == 'swat' + # test converter code that doesn't exist + resapi = self.reader.getRelatedModels(code='None') - # test model code that doesn't exist - resapi = self.reader.getRelatedModelsByCode('None') assert resapi is not None assert len(resapi) == 0 # test invalid argument - resapi = self.reader.getRelatedModelsByCode(models.ActionBy) - assert resapi is None + resapi = self.reader.getRelatedModels(code=234123) + assert not resapi -# ################################################################################ -# Simulations -# ################################################################################ +# Results + """ + TABLE Results ( + ResultID INTEGER NOT NULL PRIMARY KEY, + ResultUUID VARCHAR(36) NOT NULL, + FeatureActionID INTEGER NOT NULL, + ResultTypeCV VARCHAR (255) NOT NULL, + VariableID INTEGER NOT NULL, + UnitsID INTEGER NOT NULL, + TaxonomicClassifierID INTEGER NULL, + ProcessingLevelID INTEGER NOT NULL, + ResultDateTime DATETIME NULL, + ResultDateTimeUTCOffset INTEGER NULL, + ValidDateTime DATETIME NULL, + ValidDateTimeUTCOffset INTEGER NULL, + StatusCV VARCHAR (255) NULL, + SampledMediumCV VARCHAR (255) NOT NULL, + ValueCount INTEGER NOT NULL + """ + def test_getAllResults(self): + # get all results from the database + res = self.engine.execute('SELECT * FROM Results').fetchall() + print(res) + # get all results using the api + resapi = self.reader.getResults() + assert len(res) == len(resapi) + + def test_getResultsByID(self): + # get a result from the database + res = self.engine.execute('SELECT * FROM Results').fetchone() + resultid = res[1] + + # get the result using the api + resapi = self.reader.getResults(ids=[resultid]) + assert resapi is not None +# Simulations """ TABLE Simulations ( SimulationID INTEGER NOT NULL PRIMARY KEY, @@ -179,56 +210,48 @@ def test_getRelatedModelsByCode(self): """ def test_getAllSimulations(self): - # get all simulation from the database res = self.engine.execute('SELECT * FROM Simulations').fetchall() - # get all simulations using the api - resapi = self.reader.getAllSimulations() - + resapi = self.reader.getSimulations() assert len(res) == len(resapi) def test_getSimulationByName(self): - # get a simulation from the database res = self.engine.execute('SELECT * FROM Simulations').fetchone() simName = res[2] - # get simulation by name using the api - resapi = self.reader.getSimulationByName(simulationName=simName) + resapi = self.reader.getSimulations(name=simName) assert resapi is not None def test_getSimulationByActionID(self): - # get a simulation from the database res = self.engine.execute('SELECT * FROM Simulations').fetchone() actionID = res[1] - # get simulation by actionid using the api - resapi = self.reader.getSimulationByActionID(actionID=actionID) + resapi = self.reader.getSimulations(actionid=actionID) assert resapi is not None def test_getResultsBySimulationID(self): - # get a simulation from the database res = self.engine.execute('SELECT * FROM Simulations').fetchone() simulation = rawSql2Alchemy(res, models.Simulations) - # get the results id associated with the simulation - res = self.engine.execute('SELECT * from Results as r '\ - 'inner join FeatureActions as fa on fa.FeatureActionID == r.FeatureActionID ' \ - 'inner join Actions as a on a.ActionID == fa.ActionID ' \ - 'inner join Simulations as s on s.ActionID == a.ActionID '\ - 'where s.SimulationID = 1').first() + res = self.engine.execute( + 'SELECT * from Results as r ' + 'inner join FeatureActions as fa on fa.FeatureActionID == r.FeatureActionID ' + 'inner join Actions as a on a.ActionID == fa.ActionID ' + 'inner join Simulations as s on s.ActionID == a.ActionID ' + 'where s.SimulationID = 1' + ).first() assert len(res) > 0 res = rawSql2Alchemy(res, models.Results) - print res + print(res) # get simulation by id using the api - resapi = self.reader.getResultsBySimulationID(simulation.SimulationID) + # resapi = self.reader.getResultsBySimulationID(simulation.SimulationID) + resapi = self.reader.getResults(simulationid=simulation.SimulationID) + assert resapi is not None assert len(resapi) > 0 assert res.ResultID == resapi[0].ResultID - - - diff --git a/tests/test_util1_1_1.py b/tests/test_util1_1_1.py deleted file mode 100644 index 3fc9cf0..0000000 --- a/tests/test_util1_1_1.py +++ /dev/null @@ -1,291 +0,0 @@ -import datetime - -from odm2api.ODM1_1_1.models import * -from odm2api import base as Base - -def build_db(engine): - Base.metadata.create_all(engine) - - -# Create DB objects # - -# Create Series objects -def add_series(session): - site = add_site(session) - var = add_variable(session) - qcl = add_qcl(session) - method = add_method(session) - source = add_source(session) - - series = Series() - series.site = site - series.site_code = site.code - series.variable = var - series.variable_code = var.code - series.method = method - series.source = source - series.quality_control_level_id = qcl.id - - dvs = add_data_values(session, series) - series.begin_date_time = dvs[0].local_date_time - series.end_date_time = dvs[-1].local_date_time - series.begin_date_time_utc = dvs[0].date_time_utc - series.end_date_time_utc = dvs[-1].date_time_utc - - session.add(series) - session.commit() - return series - - -def add_data_values(session, series): - dvs = [] - for i in range(10): - dv = DataValue() - dv.data_value = i - dv.local_date_time = datetime.datetime.now() - datetime.timedelta(days=i) - dv.utc_offset = 0 - dv.date_time_utc = dv.local_date_time - dv.site_id = series.site_id - dv.variable_id = series.variable_id - dv.censor_code = "NC" - dv.method_id = series.method_id - dv.source_id = series.source_id - dv.quality_control_level_id = series.quality_control_level_id - dvs.append(dv) - - series.data_values = dvs - session.add_all(dvs) - session.commit() - return dvs - - -def add_site(session): - spatial_ref = add_spatial_reference(session) - site = Site("ABC123", "Test Site") - site.latitude = 10.0 - site.longitude = 10.0 - site.lat_long_datum_id = spatial_ref.id - site.local_projection_id = spatial_ref.id - site.elevation_m = 1000 - site.local_x = 10.0 - site.local_y = 10.0 - session.add(site) - session.commit() - return site - - -def add_variable(session): - unit = add_unit(session) - variable = Variable() - variable.code = "ABC123" - variable.name = "Test Variable" - variable.speciation = "Test" - variable.variable_unit_id = unit.id - variable.sample_medium = "Test Medium" - variable.value_type = "Test Val Type" - variable.is_regular = True - variable.time_support = 3.14 - variable.time_unit_id = unit.id - variable.data_type = "Test Data Type" - variable.general_category = "Test Category" - variable.no_data_value = -2000.0 - session.add(variable) - session.commit() - return variable - - -def add_method(session): - method = Method() - method.description = "This is a test" - session.add(method) - session.commit() - return method - - -def add_qcl(session): - qcl = QualityControlLevel() - qcl.code = "ABC123" - qcl.definition = "This is a test" - qcl.explanation = "A test is a thing that tests code" - session.add(qcl) - session.commit() - return qcl - - -def add_source(session): - source = Source() - source.organization = "Test Organization" - source.description = "This is a test" - source.contact_name = "Test Name" - source.phone = "555-1234" - source.email = "source@example.com" - source.address = "123 Test Street" - source.city = "Metropolis" - source.state = "NY" - source.zip_code = "12345" - source.citation = "Test Citation" - - iso = add_iso_metadata(session) - source.iso_metadata_id = iso.id - session.add(source) - session.commit() - return source - - -def add_iso_metadata(session): - iso = ISOMetadata() - iso.topic_category = "Test Topic" - iso.title = "Test Title" - iso.abstract = "Test Abstract" - iso.profile_version = "1.0.0.0rc4" - session.add(iso) - session.commit() - return iso - - -def add_spatial_reference(session): - spatial_ref = SpatialReference() - spatial_ref.srs_name = "This is a test" - session.add(spatial_ref) - session.commit() - return spatial_ref - - -# Create CVs # -def add_vertical_datum_cv(session): - vert_dat = VerticalDatumCV() - vert_dat.term = "Test" - vert_dat.definition = "This is a test" - session.add(vert_dat) - session.commit() - return vert_dat - - -def add_lab_method(session): - lab_method = LabMethod() - lab_method.name = "Test Lab" - lab_method.organization = "Test Org" - lab_method.method_name = "Test Method" - lab_method.method_description = "Test Description" - lab_method.method_link = "Test Link" - session.add(lab_method) - session.commit() - return lab_method - - -def add_sample(session, lab_method_id): - sample = Sample() - sample.type = "Test" - sample.lab_sample_code = "ABC123" - sample.lab_method_id = lab_method_id - session.add(sample) - session.commit() - return sample - - -def add_site_type_cv(session): - st_cv = SiteTypeCV() - st_cv.term = "Test" - st_cv.definition = "This is a test" - session.add(st_cv) - session.commit() - return st_cv - - -def add_variable_name_cv(session): - var_name_cv = VariableNameCV() - var_name_cv.term = "Test" - var_name_cv.definition = "This is a test" - session.add(var_name_cv) - session.commit() - return var_name_cv - - -def add_unit(session): - unit = Unit() - unit.name = "Test" - unit.type = "Test" - unit.abbreviation = "T" - session.add(unit) - session.commit() - return unit - - -def add_offset_type_cv(session, unit_id): - offset = OffsetType() - offset.unit_id = unit_id - offset.description = "This is a test" - session.add(offset) - session.commit() - return offset - - -def add_speciation_cv(session): - spec = SpeciationCV() - spec.term = "Test" - spec.definition = "This is a test" - session.add(spec) - session.commit() - return spec - - -def add_sample_medium_cv(session): - samp_med = SampleMediumCV() - samp_med.term = "Test" - samp_med.definition = "This is a test" - session.add(samp_med) - session.commit() - return samp_med - - -def add_value_type_cv(session): - value_type = ValueTypeCV() - value_type.term = "Test" - value_type.definition = "This is a test" - session.add(value_type) - session.commit() - return value_type - - -def add_data_type_cv(session): - data_type = DataTypeCV() - data_type.term = "Test" - data_type.definition = "This is a test" - session.add(data_type) - session.commit() - return data_type - - -def add_general_category_cv(session): - gen_cat = GeneralCategoryCV() - gen_cat.term = "Test" - gen_cat.definition = "This is a test" - session.add(gen_cat) - session.commit() - return gen_cat - - -def add_censor_code_cv(session): - censor = CensorCodeCV() - censor.term = "Test" - censor.definition = "This is a test" - session.add(censor) - session.commit() - return censor - - -def add_sample_type_cv(session): - sample_type = SampleTypeCV() - sample_type.term = "Test" - sample_type.definition = "This is a test" - session.add(sample_type) - session.commit() - return sample_type - - -def add_version(session): - version = ODMVersion() - version.version_number = "1.0.0.0.1alpha" - session.add(version) - session.commit() - return version \ No newline at end of file diff --git a/tests/usecasesql/littlebearriver/sampledatabases/odm2_ms_sql_server/LBR_ODM2_MSSQLDump.sql b/tests/usecasesql/littlebearriver/sampledatabases/odm2_ms_sql_server/LBR_ODM2_MSSQLDump.sql index 90bbc55..e07fba6 100644 Binary files a/tests/usecasesql/littlebearriver/sampledatabases/odm2_ms_sql_server/LBR_ODM2_MSSQLDump.sql and b/tests/usecasesql/littlebearriver/sampledatabases/odm2_ms_sql_server/LBR_ODM2_MSSQLDump.sql differ diff --git a/tests/usecasesql/littlebearriver/sampledatabases/odm2_mysql/LBR_MySQL_SmallExample.sql b/tests/usecasesql/littlebearriver/sampledatabases/odm2_mysql/LBR_MySQL_SmallExample.sql index 73dfc59..dbb5b8c 100644 --- a/tests/usecasesql/littlebearriver/sampledatabases/odm2_mysql/LBR_MySQL_SmallExample.sql +++ b/tests/usecasesql/littlebearriver/sampledatabases/odm2_mysql/LBR_MySQL_SmallExample.sql @@ -2916,6 +2916,7 @@ CREATE TABLE `SamplingFeatures` ( `SamplingFeatureDescription` varchar(500) DEFAULT NULL, `SamplingFeatureGeotypeCV` varchar(255) DEFAULT NULL, `FeatureGeometry` geometry DEFAULT NULL, + `FeatureGeometryWKT` varchar(50) DEFAULT NULL, `Elevation_m` double DEFAULT NULL, `ElevationDatumCV` varchar(255) DEFAULT NULL, PRIMARY KEY (`SamplingFeatureID`), @@ -2934,7 +2935,7 @@ CREATE TABLE `SamplingFeatures` ( -- /*!40000 ALTER TABLE `SamplingFeatures` DISABLE KEYS */; -INSERT INTO `SamplingFeatures` VALUES (1,'68D74A4B-FD6E-E511-9449-6C4008BF018F','Site','USU-LBR-Mendon','Little Bear River at Mendon Road near Mendon, Utah','Located below county road bridge at Mendon Road crossing','Point','\0\0\0\0\0\0\0ž·±Ù‘ü[ÀŽ[ìöÛD@',1345,'NGVD29'),(14,'69D74A4B-FD6E-E511-9449-6C4008BF018F','Site','USU-LBR-SFWeather','Little Bear River South Fork Weather Station near Avon, Utah','This is a continuous weather station.','Point','\0\0\0\0\0\0\08gDioô[À+ö—Ý“¿D@',1601,'NGVD29'),(15,'C7D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','11/13 TDP E',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(16,'C8D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','11/13 TP E',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(17,'C9D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','11/21 TDP G',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(18,'CAD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','11/21 TP G',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(19,'CBD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','8355',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(20,'CCD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','8469',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(21,'CDD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','8594',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(22,'CED74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','8719',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(23,'CFD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','9113',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(24,'D0D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','9184',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(25,'D1D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','9393',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(26,'D2D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','9506',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(27,'D3D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-0:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(28,'D4D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-0:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(29,'D5D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-13:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(30,'D6D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-19:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(31,'D7D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-21:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(32,'D8D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-3:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(33,'D9D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-3:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(34,'DAD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-5:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(35,'DBD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-6:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(36,'DCD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020907-PAR-14:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(37,'DDD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020907-PAR-6:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(38,'DED74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020907-PAR-9:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(39,'DFD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-0:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(40,'E0D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-11:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(41,'E1D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-12:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(42,'E2D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-13:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(43,'E3D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-16:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(44,'E4D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(45,'E5D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-18:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(46,'E6D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-2:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(47,'E7D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-20:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(48,'E8D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-22:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(49,'E9D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-6:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(50,'EAD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-9:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(51,'EBD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030106-PAR-20:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(52,'ECD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030106-PAR-21:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(53,'EDD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030206-PAR-12:16-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(54,'EED74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030206-PAR-21:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(55,'EFD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030306-PAR-11:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(56,'F0D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030306-PAR-22:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(57,'F1D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030406-PAR-13:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(58,'F2D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030406-PAR-13:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(59,'F3D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030506-PAR-12:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(60,'F4D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030506-PAR-18:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(61,'F5D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030606-PAR-10:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(62,'F6D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030606-PAR-10:55-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(63,'F7D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030606-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(64,'F8D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030606-PAR-20:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(65,'F9D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-12:16-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(66,'FAD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-14:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(67,'FBD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-15:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(68,'FCD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-17:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(69,'FDD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(70,'FED74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-20:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(71,'FFD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-21:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(72,'00D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-21:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(73,'01D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-4:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(74,'02D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-9:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(75,'03D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-0:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(76,'04D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-10:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(77,'05D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-15:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(78,'06D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-19:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(79,'07D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-3:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(80,'08D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-5:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(81,'09D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-6:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(82,'0AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-6:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(83,'0BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-7:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(84,'0CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031007-PAR-10:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(85,'0DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031007-PAR-14:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(86,'0ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031007-PAR-9:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(87,'0FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-12:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(88,'10D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-15:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(89,'11D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-18:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(90,'12D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-19:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(91,'13D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-22:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(92,'14D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-7:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(93,'15D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031706-PAR-11:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(94,'16D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031806-PAR-12:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(95,'17D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031806-PAR-13:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(96,'18D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031906-PAR-10:55-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(97,'19D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-0:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(98,'1AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-10:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(99,'1BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-13:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(100,'1CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(101,'1DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-19:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(102,'1ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-19:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(103,'1FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-2:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(104,'20D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-21:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(105,'21D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-6:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(106,'22D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-12:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(107,'23D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-13:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(108,'24D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-14:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(109,'25D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-14:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(110,'26D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(111,'27D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-21:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(112,'28D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-14:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(113,'29D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-15:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(114,'2AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-16:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(115,'2BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-16:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(116,'2CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-17:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(117,'2DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-17:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(118,'2ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-18:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(119,'2FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-18:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(120,'30D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-19:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(121,'31D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-2:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(122,'32D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-21:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(123,'33D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-4:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(124,'34D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-4:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(125,'35D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-8:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(126,'36D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-9:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(127,'37D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-0:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(128,'38D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-0:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(129,'39D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-10:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(130,'3AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-15:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(131,'3BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-16:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(132,'3CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-20:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(133,'3DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-23:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(134,'3ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-7:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(135,'3FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-9:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(136,'40D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-10:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(137,'41D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-12:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(138,'42D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-13:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(139,'43D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-2:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(140,'44D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-20:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(141,'45D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-21:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(142,'46D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-22:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(143,'47D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-23:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(144,'48D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-5:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(145,'49D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-5:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(146,'4AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-7:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(147,'4BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-9:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(148,'4CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032807-PAR-12:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(149,'4DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032807-PAR-18:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(150,'4ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032807-PAR-5:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(151,'4FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-0:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(152,'50D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-10:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(153,'51D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-10:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(154,'52D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-11:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(155,'53D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-14:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(156,'54D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-14:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(157,'55D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-15:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(158,'56D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-16:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(159,'57D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(160,'58D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-18:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(161,'59D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-18:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(162,'5AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-18:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(163,'5BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-2:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(164,'5CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-20:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(165,'5DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-20:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(166,'5ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-21:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(167,'5FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-21:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(168,'60D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-21:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(169,'61D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-4:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(170,'62D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-4:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(171,'63D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-5:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(172,'64D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-0:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(173,'65D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-10:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(174,'66D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-11:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(175,'67D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-12:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(176,'68D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-14:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(177,'69D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-14:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(178,'6AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-16:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(179,'6BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-18:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(180,'6CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-20:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(181,'6DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-21:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(182,'6ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-3:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(183,'6FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-6:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(184,'70D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-7:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(185,'71D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-8:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(186,'72D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-9:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(187,'73D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-11:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(188,'74D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-13:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(189,'75D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(190,'76D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-2:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(191,'77D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-21:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(192,'78D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-4:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(193,'79D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-0:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(194,'7AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-0:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(195,'7BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-0:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(196,'7CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-10:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(197,'7DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-10:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(198,'7ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-10:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(199,'7FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-11:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(200,'80D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-11:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(201,'81D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-12:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(202,'82D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-13:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(203,'83D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-14:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(204,'84D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-15:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(205,'85D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-18:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(206,'86D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-18:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(207,'87D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-19:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(208,'88D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-20:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(209,'89D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-21:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(210,'8AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-21:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(211,'8BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-21:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(212,'8CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-22:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(213,'8DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-3:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(214,'8ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-3:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(215,'8FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-4:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(216,'90D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-4:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(217,'91D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-5:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(218,'92D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-6:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(219,'93D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-6:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(220,'94D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-7:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(221,'95D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-8:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(222,'96D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-9:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(223,'97D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-0:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(224,'98D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-0:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(225,'99D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-10:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(226,'9AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-19:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(227,'9BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-20:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(228,'9CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-22:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(229,'9DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-3:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(230,'9ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-3:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(231,'9FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-6:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(232,'A0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041406-PAR-3:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(233,'A1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041406-PAR-6:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(234,'A2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041406-PAR-9:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(235,'A3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-10:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(236,'A4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-11:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(237,'A5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-11:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(238,'A6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-12:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(239,'A7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-12:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(240,'A8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-13:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(241,'A9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-13:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(242,'AAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-21:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(243,'ABD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-3:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(244,'ACD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-6:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(245,'ADD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-7:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(246,'AED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-8:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(247,'AFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP051905-PAR-19:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(248,'B0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-19:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(249,'B1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-19:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(250,'B2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-21:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(251,'B3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-7:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(252,'B4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-9:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(253,'B5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-0:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(254,'B6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-13:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(255,'B7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-14:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(256,'B8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-15:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(257,'B9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-15:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(258,'BAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-18:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(259,'BBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-19:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(260,'BCD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-20:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(261,'BDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-4:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(262,'BED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-6:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(263,'BFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-8:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(264,'C0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-9:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(265,'C1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-10:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(266,'C2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-12:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(267,'C3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-14:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(268,'C4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-15:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(269,'C5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-16:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(270,'C6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(271,'C7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-18:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(272,'C8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-19:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(273,'C9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-22:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(274,'CAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-22:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(275,'CBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-3:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(276,'CCD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-5:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(277,'CDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-6:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(278,'CED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-6:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(279,'CFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-6:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(280,'D0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-0:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(281,'D1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-10:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(282,'D2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-12:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(283,'D3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-18:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(284,'D4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-2:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(285,'D5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-21:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(286,'D6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-21:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(287,'D7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-6:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(288,'D8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-7:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(289,'D9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081605-PAR-0:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(290,'DAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081705-PAR-15:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(291,'DBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081705-PAR-20:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(292,'DCD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081705-PAR-23:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(293,'DDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081705-PAR-5:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(294,'DED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-0:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(295,'DFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-0:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(296,'E0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-0:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(297,'E1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-14:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(298,'E2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-15:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(299,'E3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-16:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(300,'E4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-18:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(301,'E5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-19:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(302,'E6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-2:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(303,'E7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-20:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(304,'E8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-20:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(305,'E9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-22:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(306,'EAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-4:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(307,'EBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-4:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(308,'ECD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-6:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(309,'EDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-8:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(310,'EED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-9:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(311,'EFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-9:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(312,'F0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-0:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(313,'F1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-10:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(314,'F2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-16:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(315,'F3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-18:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(316,'F4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-3:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(317,'F5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-6:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(318,'F6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-6:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(319,'F7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-7:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(320,'F8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-9:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(321,'F9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-11:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(322,'FAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-12:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(323,'FBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-12:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(324,'FCD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-12:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(325,'FDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-13:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(326,'FED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-15:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(327,'FFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-15:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(328,'00D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(329,'01D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-18:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(330,'02D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102705-PAR-15:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(331,'03D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102705-PAR-18:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(332,'04D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102705-PAR-19:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(333,'05D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102705-PAR-9:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(334,'06D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-0:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(335,'07D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-0:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(336,'08D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-0:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(337,'09D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-0:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(338,'0AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-1:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(339,'0BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-1:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(340,'0CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-10:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(341,'0DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-11:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(342,'0ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-11:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(343,'0FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-11:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(344,'10D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-12:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(345,'11D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-13:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(346,'12D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-14:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(347,'13D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-14:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(348,'14D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-15:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(349,'15D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-15:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(350,'16D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-15:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(351,'17D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-18:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(352,'18D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-19:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(353,'19D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-2:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(354,'1AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-2:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(355,'1BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-2:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(356,'1CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-20:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(357,'1DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-20:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(358,'1ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-21:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(359,'1FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-21:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(360,'20D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-21:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(361,'21D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-22:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(362,'22D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-22:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(363,'23D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-22:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(364,'24D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-22:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(365,'25D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-23:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(366,'26D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-23:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(367,'27D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-23:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(368,'28D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-23:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(369,'29D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-3:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(370,'2AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-3:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(371,'2BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-4:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(372,'2CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-4:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(373,'2DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-4:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(374,'2ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-4:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(375,'2FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-5:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(376,'30D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-5:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(377,'31D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-5:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(378,'32D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-6:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(379,'33D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-6:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(380,'34D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-7:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(381,'35D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-7:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(382,'36D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-7:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(383,'37D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-8:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(384,'38D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-8:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(385,'39D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-9:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(386,'3AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-9:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(387,'3BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-0:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(388,'3CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-1:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(389,'3DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-10:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(390,'3ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-10:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(391,'3FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-11:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(392,'40D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-11:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(393,'41D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-11:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(394,'42D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-12:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(395,'43D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-12:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(396,'44D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-13:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(397,'45D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-13:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(398,'46D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-14:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(399,'47D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-14:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(400,'48D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-15:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(401,'49D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-15:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(402,'4AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-16:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(403,'4BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-16:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(404,'4CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-17:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(405,'4DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-17:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(406,'4ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-17:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(407,'4FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-18:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(408,'50D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-18:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(409,'51D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-18:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(410,'52D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-19:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(411,'53D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-2:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(412,'54D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-20:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(413,'55D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-3:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(414,'56D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-4:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(415,'57D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-5:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(416,'58D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-6:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(417,'59D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-7:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(418,'5AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-7:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(419,'5BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-8:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(420,'5CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-8:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(421,'5DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-9:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(422,'5ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-9:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(423,'5FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-11:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(424,'60D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-12:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(425,'61D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-13:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(426,'62D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-14:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(427,'63D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-19:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(428,'64D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-19:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(429,'65D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-20:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(430,'66D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-20:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(431,'67D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-21:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(432,'68D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-10:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(433,'69D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-11:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(434,'6AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-12:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(435,'6BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-12:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(436,'6CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-13:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(437,'6DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-13:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(438,'6ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-14:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(439,'6FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-15:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(440,'70D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-15:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(441,'71D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-15:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(442,'72D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-16:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(443,'73D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-16:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(444,'74D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-17:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(445,'75D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-17:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(446,'76D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(447,'77D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-18:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(448,'78D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-18:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(449,'79D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-18:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(450,'7AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-19:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(451,'7BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-19:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(452,'7CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-20:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(453,'7DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-20:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(454,'7ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-20:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(455,'7FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-22:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(456,'80D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G01008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(457,'81D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(458,'82D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(459,'83D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(460,'84D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010609-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(461,'85D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010609-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(462,'86D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010609-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(463,'87D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G011708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(464,'88D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G011708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(465,'89D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G011708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(466,'8AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G011708-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(467,'8BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G012209-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(468,'8CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G012209-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(469,'8DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G012209-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(470,'8ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(471,'8FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(472,'90D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(473,'91D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(474,'92D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(475,'93D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G020509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(476,'94D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G020509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(477,'95D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G020509-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(478,'96D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G020509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(479,'97D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021208-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(480,'98D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021208-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(481,'99D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021208-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(482,'9AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021208-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(483,'9BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021909-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(484,'9CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021909-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(485,'9DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021909-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(486,'9ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021909-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(487,'9FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G022808-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(488,'A0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G022808-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(489,'A1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G022808-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(490,'A2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(491,'A3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(492,'A4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(493,'A5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030509-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(494,'A6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030608-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(495,'A7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030608-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(496,'A8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030608-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(497,'A9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(498,'AAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(499,'ABD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(500,'ACD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031909-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(501,'ADD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031909-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(502,'AED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031909-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(503,'AFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(504,'B0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032008-MEN-F-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(505,'B1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(506,'B2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(507,'B3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(508,'B4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(509,'B5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(510,'B6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032709-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(511,'B7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032709-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(512,'B8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032709-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(513,'B9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040109-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(514,'BAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040109-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(515,'BBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040109-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(516,'BCD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040109-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(517,'BDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(518,'BED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(519,'BFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(520,'C0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040809-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(521,'C1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040809-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(522,'C2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040809-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(523,'C3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(524,'C4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(525,'C5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041008-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(526,'C6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(527,'C7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(528,'C8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(529,'C9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041609-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(530,'CAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041609-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(531,'CBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041609-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(532,'CCD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042309-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(533,'CDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042309-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(534,'CED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042309-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(535,'CFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042309-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(536,'D0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(537,'D1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(538,'D2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(539,'D3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(540,'D4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(541,'D5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(542,'D6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(543,'D7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(544,'D8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050108-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(545,'D9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050108-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(546,'DAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050108-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(547,'DBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(548,'DCD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(549,'DDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(550,'DED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(551,'DFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(552,'E0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(553,'E1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051209-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(554,'E2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051209-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(555,'E3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051209-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(556,'E4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051508-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(557,'E5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051508-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(558,'E6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051508-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(559,'E7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052109-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(560,'E8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052109-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(561,'E9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052109-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(562,'EAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052109-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(563,'EBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(564,'ECD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(565,'EDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(566,'EED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052308-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(567,'EFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052809-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(568,'F0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052809-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(569,'F1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052809-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(570,'F2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052908-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(571,'F3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052908-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(572,'F4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052908-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(573,'F5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052908-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(574,'F6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060409-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(575,'F7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060409-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(576,'F8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060409-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(577,'F9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060608-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(578,'FAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060608-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(579,'FBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060608-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(580,'FCD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(581,'FDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(582,'FED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(583,'FFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061109-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(584,'00DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061109-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(585,'01DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061109-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(586,'02DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061709-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(587,'03DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061709-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(588,'04DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061709-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(589,'05DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061709-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(590,'06DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061908-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(591,'07DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061908-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(592,'08DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061908-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(593,'09DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061908-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(594,'0ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(595,'0BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(596,'0CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(597,'0DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062608-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(598,'0EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062608-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(599,'0FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062608-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(600,'10DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(601,'11DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(602,'12DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(603,'13DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070909-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(604,'14DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070909-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(605,'15DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070909-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(606,'16DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G071008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(607,'17DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G071008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(608,'18DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G071008-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(609,'19DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G071008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(610,'1ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072309-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(611,'1BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072309-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(612,'1CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072309-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(613,'1DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072508-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(614,'1EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072508-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(615,'1FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072508-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(616,'20DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(617,'21DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(618,'22DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(619,'23DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(620,'24DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(621,'25DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(622,'26DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082009-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(623,'27DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082009-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(624,'28DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082009-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(625,'29DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(626,'2ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-F-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(627,'2BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(628,'2CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(629,'2DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(630,'2EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G090209-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(631,'2FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G090209-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(632,'30DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G090209-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(633,'31DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G090209-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(634,'32DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091208-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(635,'33DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091208-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(636,'34DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091208-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(637,'35DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091208-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(638,'36DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(639,'37DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(640,'38DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(641,'39DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(642,'3ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(643,'3BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G092608-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(644,'3CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G092608-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(645,'3DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G092608-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(646,'3EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G092608-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(647,'3FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G100109-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(648,'40DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G100109-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(649,'41DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G100109-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(650,'42DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(651,'43DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(652,'44DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101008-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(653,'45DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(654,'46DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(655,'47DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(656,'48DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101509-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(657,'49DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(658,'4ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(659,'4BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(660,'4CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(661,'4DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102909-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(662,'4EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102909-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(663,'4FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102909-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(664,'50DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(665,'51DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(666,'52DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(667,'53DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(668,'54DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(669,'55DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111209-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(670,'56DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111209-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(671,'57DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111209-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(672,'58DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(673,'59DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(674,'5ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(675,'5BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(676,'5CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(677,'5DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G112409-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(678,'5EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G112409-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(679,'5FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G112409-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(680,'60DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(681,'61DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(682,'62DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(683,'63DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120507-MEN-TDP',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(684,'64DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120507-MEN-TP',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(685,'65DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120507-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(686,'66DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121009-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(687,'67DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121009-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(688,'68DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121009-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(689,'69DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121808-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(690,'6ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121808-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(691,'6BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121808-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(692,'6CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G122007-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(693,'6DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G122007-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(694,'6EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G122007-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(695,'6FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4509 #5 Mendon Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(696,'70DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4509 #6 Mendon Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(697,'71DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4579 Mendon Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(698,'72DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4579 Mendon Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(699,'73DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4655 Mendon Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(700,'74DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4655 Mendon Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(701,'75DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4736 Mendon Filtered ',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(702,'76DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4736 Mendon Unfiltered ',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(703,'77DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4855 Mendon Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(704,'78DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4855 Mendon Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(705,'79DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4924 J Filtered ',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(706,'7ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4924 J Unfiltered ',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(707,'7BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4988 Mendon B Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(708,'7CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4988 Mendon B Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(709,'7DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4988 Mendon C Filtered -D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(710,'7EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4988 Mendon C Unfiltered -D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(711,'7FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-5112 P Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL),(712,'80DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-5112 P Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL); +INSERT INTO `SamplingFeatures` VALUES (1,'68D74A4B-FD6E-E511-9449-6C4008BF018F','Site','USU-LBR-Mendon','Little Bear River at Mendon Road near Mendon, Utah','Located below county road bridge at Mendon Road crossing','Point','\0\0\0\0\0\0\0ž·±Ù‘ü[ÀŽ[ìöÛD@',NULL, 1345,'NGVD29'),(14,'69D74A4B-FD6E-E511-9449-6C4008BF018F','Site','USU-LBR-SFWeather','Little Bear River South Fork Weather Station near Avon, Utah','This is a continuous weather station.','Point','\0\0\0\0\0\0\08gDioô[À+ö—Ý“¿D@',NULL, 1601,'NGVD29'),(15,'C7D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','11/13 TDP E',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(16,'C8D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','11/13 TP E',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(17,'C9D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','11/21 TDP G',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(18,'CAD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','11/21 TP G',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(19,'CBD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','8355',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(20,'CCD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','8469',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(21,'CDD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','8594',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(22,'CED74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','8719',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(23,'CFD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','9113',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(24,'D0D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','9184',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(25,'D1D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','9393',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(26,'D2D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','9506',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(27,'D3D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-0:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(28,'D4D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-0:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(29,'D5D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-13:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(30,'D6D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-19:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(31,'D7D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-21:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(32,'D8D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-3:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(33,'D9D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-3:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(34,'DAD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-5:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(35,'DBD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020807-PAR-6:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(36,'DCD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020907-PAR-14:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(37,'DDD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020907-PAR-6:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(38,'DED74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP020907-PAR-9:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(39,'DFD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-0:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(40,'E0D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-11:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(41,'E1D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-12:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(42,'E2D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-13:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(43,'E3D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-16:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(44,'E4D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(45,'E5D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-18:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(46,'E6D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-2:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(47,'E7D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-20:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(48,'E8D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-22:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(49,'E9D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-6:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(50,'EAD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP021607-PAR-9:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(51,'EBD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030106-PAR-20:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(52,'ECD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030106-PAR-21:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(53,'EDD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030206-PAR-12:16-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(54,'EED74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030206-PAR-21:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(55,'EFD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030306-PAR-11:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(56,'F0D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030306-PAR-22:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(57,'F1D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030406-PAR-13:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(58,'F2D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030406-PAR-13:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(59,'F3D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030506-PAR-12:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(60,'F4D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030506-PAR-18:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(61,'F5D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030606-PAR-10:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(62,'F6D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030606-PAR-10:55-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(63,'F7D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030606-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(64,'F8D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030606-PAR-20:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(65,'F9D74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-12:16-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(66,'FAD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-14:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(67,'FBD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-15:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(68,'FCD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-17:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(69,'FDD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(70,'FED74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-20:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(71,'FFD74A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-21:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(72,'00D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-21:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(73,'01D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-4:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(74,'02D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030706-PAR-9:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(75,'03D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-0:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(76,'04D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-10:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(77,'05D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-15:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(78,'06D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-19:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(79,'07D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-3:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(80,'08D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-5:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(81,'09D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-6:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(82,'0AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-6:43-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(83,'0BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP030907-PAR-7:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(84,'0CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031007-PAR-10:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(85,'0DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031007-PAR-14:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(86,'0ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031007-PAR-9:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(87,'0FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-12:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(88,'10D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-15:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(89,'11D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-18:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(90,'12D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-19:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(91,'13D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-22:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(92,'14D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031307-PAR-7:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(93,'15D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031706-PAR-11:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(94,'16D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031806-PAR-12:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(95,'17D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031806-PAR-13:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(96,'18D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP031906-PAR-10:55-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(97,'19D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-0:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(98,'1AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-10:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(99,'1BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-13:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(100,'1CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(101,'1DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-19:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(102,'1ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-19:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(103,'1FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-2:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(104,'20D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-21:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(105,'21D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032007-PAR-6:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(106,'22D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-12:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(107,'23D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-13:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(108,'24D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-14:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(109,'25D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-14:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(110,'26D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(111,'27D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032506-PAR-21:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(112,'28D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-14:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(113,'29D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-15:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(114,'2AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-16:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(115,'2BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-16:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(116,'2CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-17:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(117,'2DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-17:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(118,'2ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-18:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(119,'2FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-18:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(120,'30D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-19:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(121,'31D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-2:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(122,'32D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-21:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(123,'33D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-4:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(124,'34D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-4:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(125,'35D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-8:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(126,'36D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032606-PAR-9:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(127,'37D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-0:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(128,'38D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-0:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(129,'39D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-10:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(130,'3AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-15:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(131,'3BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-16:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(132,'3CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-20:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(133,'3DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-23:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(134,'3ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-7:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(135,'3FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032707-PAR-9:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(136,'40D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-10:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(137,'41D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-12:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(138,'42D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-13:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(139,'43D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-2:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(140,'44D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-20:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(141,'45D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-21:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(142,'46D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-22:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(143,'47D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-23:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(144,'48D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-5:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(145,'49D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-5:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(146,'4AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-7:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(147,'4BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032806-PAR-9:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(148,'4CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032807-PAR-12:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(149,'4DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032807-PAR-18:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(150,'4ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032807-PAR-5:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(151,'4FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-0:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(152,'50D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-10:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(153,'51D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-10:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(154,'52D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-11:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(155,'53D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-14:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(156,'54D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-14:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(157,'55D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-15:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(158,'56D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-16:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(159,'57D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(160,'58D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-18:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(161,'59D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-18:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(162,'5AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-18:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(163,'5BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-2:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(164,'5CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-20:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(165,'5DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-20:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(166,'5ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-21:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(167,'5FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-21:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(168,'60D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-21:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(169,'61D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-4:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(170,'62D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-4:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(171,'63D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP032906-PAR-5:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(172,'64D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-0:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(173,'65D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-10:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(174,'66D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-11:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(175,'67D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-12:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(176,'68D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-14:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(177,'69D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-14:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(178,'6AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-16:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(179,'6BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-18:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(180,'6CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-20:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(181,'6DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-21:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(182,'6ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-3:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(183,'6FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-6:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(184,'70D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-7:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(185,'71D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-8:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(186,'72D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP033006-PAR-9:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(187,'73D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-11:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(188,'74D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-13:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(189,'75D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-18:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(190,'76D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-2:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(191,'77D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-21:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(192,'78D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040406-PAR-4:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(193,'79D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-0:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(194,'7AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-0:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(195,'7BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-0:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(196,'7CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-10:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(197,'7DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-10:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(198,'7ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-10:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(199,'7FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-11:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(200,'80D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-11:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(201,'81D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-12:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(202,'82D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-13:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(203,'83D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-14:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(204,'84D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-15:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(205,'85D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-18:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(206,'86D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-18:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(207,'87D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-19:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(208,'88D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-20:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(209,'89D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-21:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(210,'8AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-21:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(211,'8BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-21:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(212,'8CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-22:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(213,'8DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-3:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(214,'8ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-3:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(215,'8FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-4:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(216,'90D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-4:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(217,'91D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-5:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(218,'92D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-6:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(219,'93D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-6:45-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(220,'94D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-7:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(221,'95D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-8:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(222,'96D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040506-PAR-9:50-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(223,'97D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-0:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(224,'98D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-0:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(225,'99D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-10:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(226,'9AD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-19:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(227,'9BD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-20:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(228,'9CD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-22:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(229,'9DD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-3:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(230,'9ED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-3:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(231,'9FD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP040606-PAR-6:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(232,'A0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041406-PAR-3:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(233,'A1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041406-PAR-6:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(234,'A2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041406-PAR-9:15-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(235,'A3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-10:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(236,'A4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-11:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(237,'A5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-11:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(238,'A6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-12:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(239,'A7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-12:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(240,'A8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-13:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(241,'A9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-13:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(242,'AAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-21:45-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(243,'ABD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-3:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(244,'ACD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-6:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(245,'ADD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-7:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(246,'AED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP041506-PAR-8:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(247,'AFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP051905-PAR-19:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(248,'B0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-19:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(249,'B1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-19:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(250,'B2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-21:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(251,'B3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-7:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(252,'B4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP052005-PAR-9:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(253,'B5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-0:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(254,'B6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-13:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(255,'B7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-14:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(256,'B8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-15:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(257,'B9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-15:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(258,'BAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-18:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(259,'BBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-19:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(260,'BCD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-20:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(261,'BDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-4:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(262,'BED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-6:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(263,'BFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-8:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(264,'C0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP060707-PAR-9:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(265,'C1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-10:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(266,'C2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-12:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(267,'C3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-14:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(268,'C4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-15:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(269,'C5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-16:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(270,'C6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(271,'C7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-18:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(272,'C8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-19:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(273,'C9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-22:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(274,'CAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-22:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(275,'CBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-3:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(276,'CCD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-5:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(277,'CDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-6:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(278,'CED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-6:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(279,'CFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072506-PAR-6:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(280,'D0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-0:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(281,'D1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-10:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(282,'D2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-12:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(283,'D3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-18:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(284,'D4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-2:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(285,'D5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-21:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(286,'D6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-21:45-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(287,'D7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-6:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(288,'D8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP072606-PAR-7:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(289,'D9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081605-PAR-0:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(290,'DAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081705-PAR-15:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(291,'DBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081705-PAR-20:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(292,'DCD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081705-PAR-23:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(293,'DDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP081705-PAR-5:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(294,'DED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-0:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(295,'DFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-0:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(296,'E0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-0:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(297,'E1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-14:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(298,'E2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-15:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(299,'E3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-16:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(300,'E4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-18:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(301,'E5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-19:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(302,'E6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-2:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(303,'E7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-20:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(304,'E8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-20:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(305,'E9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-22:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(306,'EAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-4:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(307,'EBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-4:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(308,'ECD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-6:43-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(309,'EDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-8:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(310,'EED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-9:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(311,'EFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP100405-PAR-9:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(312,'F0D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-0:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(313,'F1D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-10:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(314,'F2D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-16:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(315,'F3D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-18:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(316,'F4D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-3:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(317,'F5D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-6:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(318,'F6D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-6:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(319,'F7D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-7:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(320,'F8D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP101906-PAR-9:15-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(321,'F9D84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-11:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(322,'FAD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-12:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(323,'FBD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-12:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(324,'FCD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-12:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(325,'FDD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-13:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(326,'FED84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-15:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(327,'FFD84A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-15:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(328,'00D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(329,'01D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102006-PAR-18:15-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(330,'02D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102705-PAR-15:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(331,'03D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102705-PAR-18:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(332,'04D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102705-PAR-19:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(333,'05D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102705-PAR-9:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(334,'06D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-0:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(335,'07D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-0:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(336,'08D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-0:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(337,'09D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-0:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(338,'0AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-1:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(339,'0BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-1:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(340,'0CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-10:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(341,'0DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-11:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(342,'0ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-11:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(343,'0FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-11:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(344,'10D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-12:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(345,'11D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-13:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(346,'12D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-14:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(347,'13D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-14:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(348,'14D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-15:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(349,'15D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-15:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(350,'16D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-15:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(351,'17D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-18:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(352,'18D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-19:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(353,'19D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-2:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(354,'1AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-2:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(355,'1BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-2:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(356,'1CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-20:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(357,'1DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-20:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(358,'1ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-21:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(359,'1FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-21:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(360,'20D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-21:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(361,'21D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-22:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(362,'22D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-22:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(363,'23D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-22:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(364,'24D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-22:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(365,'25D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-23:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(366,'26D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-23:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(367,'27D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-23:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(368,'28D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-23:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(369,'29D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-3:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(370,'2AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-3:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(371,'2BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-4:00-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(372,'2CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-4:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(373,'2DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-4:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(374,'2ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-4:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(375,'2FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-5:00-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(376,'30D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-5:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(377,'31D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-5:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(378,'32D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-6:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(379,'33D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-6:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(380,'34D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-7:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(381,'35D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-7:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(382,'36D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-7:50-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(383,'37D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-8:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(384,'38D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-8:30-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(385,'39D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-9:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(386,'3AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102805-PAR-9:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(387,'3BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-0:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(388,'3CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-1:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(389,'3DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-10:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(390,'3ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-10:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(391,'3FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-11:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(392,'40D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-11:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(393,'41D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-11:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(394,'42D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-12:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(395,'43D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-12:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(396,'44D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-13:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(397,'45D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-13:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(398,'46D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-14:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(399,'47D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-14:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(400,'48D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-15:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(401,'49D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-15:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(402,'4AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-16:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(403,'4BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-16:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(404,'4CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-17:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(405,'4DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-17:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(406,'4ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-17:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(407,'4FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-18:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(408,'50D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-18:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(409,'51D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-18:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(410,'52D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-19:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(411,'53D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-2:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(412,'54D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-20:40-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(413,'55D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-3:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(414,'56D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-4:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(415,'57D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-5:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(416,'58D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-6:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(417,'59D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-7:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(418,'5AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-7:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(419,'5BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-8:30-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(420,'5CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-8:30-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(421,'5DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-9:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(422,'5ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP102905-PAR-9:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(423,'5FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-11:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(424,'60D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-12:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(425,'61D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-13:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(426,'62D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-14:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(427,'63D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-19:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(428,'64D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-19:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(429,'65D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-20:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(430,'66D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-20:40-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(431,'67D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111305-PAR-21:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(432,'68D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-10:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(433,'69D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-11:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(434,'6AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-12:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(435,'6BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-12:20-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(436,'6CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-13:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(437,'6DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-13:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(438,'6ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-14:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(439,'6FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-15:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(440,'70D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-15:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(441,'71D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-15:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(442,'72D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-16:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(443,'73D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-16:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(444,'74D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-17:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(445,'75D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-17:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(446,'76D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-18:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(447,'77D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-18:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(448,'78D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-18:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(449,'79D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-18:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(450,'7AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-19:20-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(451,'7BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-19:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(452,'7CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-20:00-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(453,'7DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-20:40-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(454,'7ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-20:50-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(455,'7FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','CEAP111405-PAR-22:20-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(456,'80D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G01008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(457,'81D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(458,'82D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(459,'83D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(460,'84D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010609-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(461,'85D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010609-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(462,'86D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G010609-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(463,'87D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G011708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(464,'88D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G011708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(465,'89D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G011708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(466,'8AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G011708-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(467,'8BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G012209-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(468,'8CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G012209-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(469,'8DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G012209-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(470,'8ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(471,'8FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(472,'90D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(473,'91D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(474,'92D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G013108-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(475,'93D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G020509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(476,'94D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G020509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(477,'95D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G020509-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(478,'96D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G020509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(479,'97D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021208-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(480,'98D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021208-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(481,'99D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021208-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(482,'9AD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021208-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(483,'9BD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021909-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(484,'9CD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021909-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(485,'9DD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021909-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(486,'9ED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G021909-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(487,'9FD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G022808-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(488,'A0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G022808-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(489,'A1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G022808-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(490,'A2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(491,'A3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(492,'A4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(493,'A5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030509-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(494,'A6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030608-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(495,'A7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030608-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(496,'A8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G030608-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(497,'A9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(498,'AAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(499,'ABD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(500,'ACD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031909-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(501,'ADD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031909-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(502,'AED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G031909-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(503,'AFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(504,'B0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032008-MEN-F-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(505,'B1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(506,'B2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(507,'B3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(508,'B4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(509,'B5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(510,'B6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032709-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(511,'B7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032709-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(512,'B8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G032709-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(513,'B9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040109-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(514,'BAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040109-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(515,'BBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040109-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(516,'BCD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040109-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(517,'BDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(518,'BED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(519,'BFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(520,'C0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040809-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(521,'C1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040809-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(522,'C2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G040809-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(523,'C3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(524,'C4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(525,'C5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041008-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(526,'C6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(527,'C7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(528,'C8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(529,'C9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041609-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(530,'CAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041609-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(531,'CBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G041609-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(532,'CCD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042309-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(533,'CDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042309-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(534,'CED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042309-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(535,'CFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042309-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(536,'D0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(537,'D1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(538,'D2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G042408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(539,'D3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(540,'D4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(541,'D5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(542,'D6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(543,'D7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G043009-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(544,'D8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050108-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(545,'D9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050108-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(546,'DAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050108-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(547,'DBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(548,'DCD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(549,'DDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(550,'DED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(551,'DFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(552,'E0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G050708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(553,'E1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051209-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(554,'E2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051209-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(555,'E3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051209-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(556,'E4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051508-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(557,'E5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051508-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(558,'E6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G051508-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(559,'E7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052109-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(560,'E8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052109-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(561,'E9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052109-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(562,'EAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052109-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(563,'EBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(564,'ECD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(565,'EDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(566,'EED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052308-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(567,'EFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052809-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(568,'F0D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052809-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(569,'F1D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052809-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(570,'F2D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052908-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(571,'F3D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052908-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(572,'F4D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052908-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(573,'F5D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G052908-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(574,'F6D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060409-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(575,'F7D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060409-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(576,'F8D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060409-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(577,'F9D94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060608-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(578,'FAD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060608-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(579,'FBD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G060608-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(580,'FCD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(581,'FDD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(582,'FED94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(583,'FFD94A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061109-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(584,'00DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061109-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(585,'01DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061109-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(586,'02DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061709-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(587,'03DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061709-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(588,'04DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061709-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(589,'05DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061709-MEN-U-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(590,'06DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061908-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(591,'07DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061908-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(592,'08DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061908-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(593,'09DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G061908-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(594,'0ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(595,'0BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(596,'0CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(597,'0DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062608-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(598,'0EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062608-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(599,'0FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G062608-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(600,'10DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070308-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(601,'11DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070308-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(602,'12DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070308-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(603,'13DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070909-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(604,'14DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070909-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(605,'15DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G070909-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(606,'16DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G071008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(607,'17DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G071008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(608,'18DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G071008-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(609,'19DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G071008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(610,'1ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072309-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(611,'1BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072309-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(612,'1CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072309-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(613,'1DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072508-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(614,'1EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072508-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(615,'1FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G072508-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(616,'20DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(617,'21DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(618,'22DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(619,'23DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(620,'24DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(621,'25DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G080509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(622,'26DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082009-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(623,'27DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082009-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(624,'28DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082009-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(625,'29DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(626,'2ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-F-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(627,'2BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(628,'2CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(629,'2DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G082108-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(630,'2EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G090209-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(631,'2FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G090209-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(632,'30DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G090209-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(633,'31DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G090209-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(634,'32DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091208-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(635,'33DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091208-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(636,'34DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091208-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(637,'35DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091208-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(638,'36DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(639,'37DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(640,'38DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(641,'39DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(642,'3ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G091709-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(643,'3BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G092608-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(644,'3CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G092608-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(645,'3DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G092608-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(646,'3EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G092608-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(647,'3FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G100109-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(648,'40DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G100109-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(649,'41DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G100109-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(650,'42DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101008-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(651,'43DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101008-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(652,'44DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101008-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(653,'45DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101008-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(654,'46DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101509-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(655,'47DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101509-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(656,'48DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101509-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(657,'49DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G101509-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(658,'4ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(659,'4BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(660,'4CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(661,'4DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102909-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(662,'4EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102909-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(663,'4FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G102909-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(664,'50DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(665,'51DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(666,'52DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(667,'53DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(668,'54DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G110708-MEN-U-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(669,'55DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111209-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(670,'56DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111209-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(671,'57DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111209-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(672,'58DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(673,'59DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-F-D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(674,'5ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(675,'5BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-TSS-R',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(676,'5CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G111708-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(677,'5DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G112409-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(678,'5EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G112409-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(679,'5FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G112409-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(680,'60DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120408-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(681,'61DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120408-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(682,'62DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120408-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(683,'63DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120507-MEN-TDP',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(684,'64DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120507-MEN-TP',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(685,'65DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G120507-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(686,'66DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121009-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(687,'67DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121009-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(688,'68DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121009-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(689,'69DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121808-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(690,'6ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121808-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(691,'6BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G121808-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(692,'6CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G122007-MEN-F',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(693,'6DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G122007-MEN-TSS',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(694,'6EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','G122007-MEN-U',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(695,'6FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4509 #5 Mendon Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(696,'70DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4509 #6 Mendon Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(697,'71DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4579 Mendon Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(698,'72DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4579 Mendon Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(699,'73DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4655 Mendon Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(700,'74DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4655 Mendon Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(701,'75DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4736 Mendon Filtered ',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(702,'76DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4736 Mendon Unfiltered ',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(703,'77DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4855 Mendon Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(704,'78DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4855 Mendon Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(705,'79DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4924 J Filtered ',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(706,'7ADA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4924 J Unfiltered ',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(707,'7BDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4988 Mendon B Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(708,'7CDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4988 Mendon B Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(709,'7DDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4988 Mendon C Filtered -D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(710,'7EDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-4988 Mendon C Unfiltered -D',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(711,'7FDA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-5112 P Filtered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL),(712,'80DA4A4B-FD6E-E511-9449-6C4008BF018F','Specimen','L07-5112 P Unfiltered',NULL,'Specimen loaded from an ODM 1.1.1 database.','Not applicable',NULL,NULL,NULL,NULL); /*!40000 ALTER TABLE `SamplingFeatures` ENABLE KEYS */; -- diff --git a/tests/usecasesql/marchantariats/marchantariats.sql b/tests/usecasesql/marchantariats/marchantariats.sql index ae77737..03eb447 100644 --- a/tests/usecasesql/marchantariats/marchantariats.sql +++ b/tests/usecasesql/marchantariats/marchantariats.sql @@ -18,7 +18,7 @@ SET client_min_messages = warning; -- Name: marchantariats; Type: DATABASE; Schema: -; Owner: - -- -CREATE DATABASE marchantariats WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8'; +CREATE DATABASE marchantariats WITH TEMPLATE = template0 ENCODING = 'UTF8' ;--LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8'; \connect marchantariats @@ -1709,6 +1709,7 @@ CREATE TABLE samplingfeatures ( samplingfeaturedescription character varying(500), samplingfeaturegeotypecv character varying(255), featuregeometry public.geometry, + featuregeometrywkt character varying(50), elevation_m double precision, elevationdatumcv character varying(255), CONSTRAINT enforce_dims_featuregeometry CHECK ((public.st_ndims(featuregeometry) = 2)) @@ -1828,7 +1829,7 @@ CREATE VIEW mappings_results_fine_particulates AS -- -- TOC entry 386 (class 1259 OID 70923) --- Name: measurementresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: measurementresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE measurementresults ( @@ -1850,7 +1851,7 @@ CREATE TABLE measurementresults ( -- -- TOC entry 219 (class 1259 OID 70024) --- Name: measurementresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: measurementresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE measurementresultvalueannotations ( @@ -1884,7 +1885,7 @@ ALTER SEQUENCE measurementresultvalueannotations_bridgeid_seq OWNED BY measureme -- -- TOC entry 388 (class 1259 OID 70933) --- Name: measurementresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: measurementresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE measurementresultvalues ( @@ -1920,7 +1921,7 @@ ALTER SEQUENCE measurementresultvalues_valueid_seq OWNED BY measurementresultval -- -- TOC entry 221 (class 1259 OID 70032) --- Name: methodannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: methodannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE methodannotations ( @@ -1954,7 +1955,7 @@ ALTER SEQUENCE methodannotations_bridgeid_seq OWNED BY methodannotations.bridgei -- -- TOC entry 373 (class 1259 OID 70867) --- Name: methodcitations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: methodcitations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE methodcitations ( @@ -1989,7 +1990,7 @@ ALTER SEQUENCE methodcitations_bridgeid_seq OWNED BY methodcitations.bridgeid; -- -- TOC entry 335 (class 1259 OID 70680) --- Name: methodextensionpropertyvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: methodextensionpropertyvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE methodextensionpropertyvalues ( @@ -2024,7 +2025,7 @@ ALTER SEQUENCE methodextensionpropertyvalues_bridgeid_seq OWNED BY methodextensi -- -- TOC entry 346 (class 1259 OID 70731) --- Name: methodexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: methodexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE methodexternalidentifiers ( @@ -2060,7 +2061,7 @@ ALTER SEQUENCE methodexternalidentifiers_bridgeid_seq OWNED BY methodexternalide -- -- TOC entry 253 (class 1259 OID 70172) --- Name: methods; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: methods; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE methods ( @@ -2098,7 +2099,7 @@ ALTER SEQUENCE methods_methodid_seq OWNED BY methods.methodid; -- -- TOC entry 420 (class 1259 OID 71098) --- Name: modelaffiliations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: modelaffiliations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE modelaffiliations ( @@ -2134,7 +2135,7 @@ ALTER SEQUENCE modelaffiliations_bridgeid_seq OWNED BY modelaffiliations.bridgei -- -- TOC entry 422 (class 1259 OID 71109) --- Name: models; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: models; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE models ( @@ -2171,7 +2172,7 @@ ALTER SEQUENCE models_modelid_seq OWNED BY models.modelid; -- -- TOC entry 255 (class 1259 OID 70183) --- Name: organizations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: organizations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE organizations ( @@ -2209,7 +2210,7 @@ ALTER SEQUENCE organizations_organizationid_seq OWNED BY organizations.organizat -- -- TOC entry 257 (class 1259 OID 70194) --- Name: people; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: people; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE people ( @@ -2244,7 +2245,7 @@ ALTER SEQUENCE people_personid_seq OWNED BY people.personid; -- -- TOC entry 348 (class 1259 OID 70742) --- Name: personexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: personexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE personexternalidentifiers ( @@ -2280,7 +2281,7 @@ ALTER SEQUENCE personexternalidentifiers_bridgeid_seq OWNED BY personexternalide -- -- TOC entry 389 (class 1259 OID 70939) --- Name: pointcoverageresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: pointcoverageresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE pointcoverageresults ( @@ -2300,7 +2301,7 @@ CREATE TABLE pointcoverageresults ( -- -- TOC entry 223 (class 1259 OID 70040) --- Name: pointcoverageresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: pointcoverageresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE pointcoverageresultvalueannotations ( @@ -2334,7 +2335,7 @@ ALTER SEQUENCE pointcoverageresultvalueannotations_bridgeid_seq OWNED BY pointco -- -- TOC entry 391 (class 1259 OID 70946) --- Name: pointcoverageresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: pointcoverageresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE pointcoverageresultvalues ( @@ -2376,7 +2377,7 @@ ALTER SEQUENCE pointcoverageresultvalues_valueid_seq OWNED BY pointcoverageresul -- -- TOC entry 259 (class 1259 OID 70205) --- Name: processinglevels; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: processinglevels; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE processinglevels ( @@ -2411,7 +2412,7 @@ ALTER SEQUENCE processinglevels_processinglevelid_seq OWNED BY processinglevels. -- -- TOC entry 392 (class 1259 OID 70955) --- Name: profileresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: profileresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE profileresults ( @@ -2431,7 +2432,7 @@ CREATE TABLE profileresults ( -- -- TOC entry 225 (class 1259 OID 70048) --- Name: profileresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: profileresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE profileresultvalueannotations ( @@ -2465,7 +2466,7 @@ ALTER SEQUENCE profileresultvalueannotations_bridgeid_seq OWNED BY profileresult -- -- TOC entry 394 (class 1259 OID 70962) --- Name: profileresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: profileresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE profileresultvalues ( @@ -2508,7 +2509,7 @@ ALTER SEQUENCE profileresultvalues_valueid_seq OWNED BY profileresultvalues.valu -- -- TOC entry 350 (class 1259 OID 70753) --- Name: referencematerialexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: referencematerialexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE referencematerialexternalidentifiers ( @@ -2544,7 +2545,7 @@ ALTER SEQUENCE referencematerialexternalidentifiers_bridgeid_seq OWNED BY refere -- -- TOC entry 301 (class 1259 OID 70514) --- Name: referencematerials; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: referencematerials; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE referencematerials ( @@ -2562,7 +2563,7 @@ CREATE TABLE referencematerials ( -- -- TOC entry 302 (class 1259 OID 70522) --- Name: referencematerialvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: referencematerialvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE referencematerialvalues ( @@ -2578,7 +2579,7 @@ CREATE TABLE referencematerialvalues ( -- -- TOC entry 261 (class 1259 OID 70216) --- Name: relatedactions; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedactions; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE relatedactions ( @@ -2613,7 +2614,7 @@ ALTER SEQUENCE relatedactions_relationid_seq OWNED BY relatedactions.relationid; -- -- TOC entry 375 (class 1259 OID 70875) --- Name: relatedannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE relatedannotations ( @@ -2648,7 +2649,7 @@ ALTER SEQUENCE relatedannotations_relationid_seq OWNED BY relatedannotations.rel -- -- TOC entry 377 (class 1259 OID 70883) --- Name: relatedcitations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedcitations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE relatedcitations ( @@ -2683,7 +2684,7 @@ ALTER SEQUENCE relatedcitations_relationid_seq OWNED BY relatedcitations.relatio -- -- TOC entry 379 (class 1259 OID 70891) --- Name: relateddatasets; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: relateddatasets; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE relateddatasets ( @@ -2719,7 +2720,7 @@ ALTER SEQUENCE relateddatasets_relationid_seq OWNED BY relateddatasets.relationi -- -- TOC entry 327 (class 1259 OID 70645) --- Name: relatedequipment; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedequipment; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE relatedequipment ( @@ -2758,7 +2759,7 @@ ALTER SEQUENCE relatedequipment_relationid_seq OWNED BY relatedequipment.relatio -- -- TOC entry 411 (class 1259 OID 71053) --- Name: relatedfeatures; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedfeatures; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE relatedfeatures ( @@ -2794,7 +2795,7 @@ ALTER SEQUENCE relatedfeatures_relationid_seq OWNED BY relatedfeatures.relationi -- -- TOC entry 424 (class 1259 OID 71120) --- Name: relatedmodels; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedmodels; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE relatedmodels ( @@ -2829,7 +2830,7 @@ ALTER SEQUENCE relatedmodels_relatedid_seq OWNED BY relatedmodels.relatedid; -- -- TOC entry 381 (class 1259 OID 70899) --- Name: relatedresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE relatedresults ( @@ -2866,7 +2867,7 @@ ALTER SEQUENCE relatedresults_relationid_seq OWNED BY relatedresults.relationid; -- -- TOC entry 227 (class 1259 OID 70056) --- Name: resultannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: resultannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE resultannotations ( @@ -2902,7 +2903,7 @@ ALTER SEQUENCE resultannotations_bridgeid_seq OWNED BY resultannotations.bridgei -- -- TOC entry 382 (class 1259 OID 70905) --- Name: resultderivationequations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: resultderivationequations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE resultderivationequations ( @@ -2913,7 +2914,7 @@ CREATE TABLE resultderivationequations ( -- -- TOC entry 337 (class 1259 OID 70688) --- Name: resultextensionpropertyvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: resultextensionpropertyvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE resultextensionpropertyvalues ( @@ -2948,7 +2949,7 @@ ALTER SEQUENCE resultextensionpropertyvalues_bridgeid_seq OWNED BY resultextensi -- -- TOC entry 303 (class 1259 OID 70527) --- Name: resultnormalizationvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: resultnormalizationvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE resultnormalizationvalues ( @@ -2959,7 +2960,7 @@ CREATE TABLE resultnormalizationvalues ( -- -- TOC entry 263 (class 1259 OID 70224) --- Name: results; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: results; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE results ( @@ -3005,7 +3006,7 @@ ALTER SEQUENCE results_resultid_seq OWNED BY results.resultid; -- -- TOC entry 305 (class 1259 OID 70534) --- Name: resultsdataquality; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: resultsdataquality; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE resultsdataquality ( @@ -3039,7 +3040,7 @@ ALTER SEQUENCE resultsdataquality_bridgeid_seq OWNED BY resultsdataquality.bridg -- -- TOC entry 229 (class 1259 OID 70064) --- Name: samplingfeatureannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: samplingfeatureannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE samplingfeatureannotations ( @@ -3073,7 +3074,7 @@ ALTER SEQUENCE samplingfeatureannotations_bridgeid_seq OWNED BY samplingfeaturea -- -- TOC entry 339 (class 1259 OID 70696) --- Name: samplingfeatureextensionpropertyvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: samplingfeatureextensionpropertyvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE samplingfeatureextensionpropertyvalues ( @@ -3108,7 +3109,7 @@ ALTER SEQUENCE samplingfeatureextensionpropertyvalues_bridgeid_seq OWNED BY samp -- -- TOC entry 352 (class 1259 OID 70764) --- Name: samplingfeatureexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: samplingfeatureexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE samplingfeatureexternalidentifiers ( @@ -3166,7 +3167,7 @@ ALTER SEQUENCE samplingfeatures_samplingfeatureid_seq OWNED BY samplingfeatures. -- -- TOC entry 395 (class 1259 OID 70971) --- Name: sectionresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: sectionresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE sectionresults ( @@ -3186,7 +3187,7 @@ CREATE TABLE sectionresults ( -- -- TOC entry 231 (class 1259 OID 70072) --- Name: sectionresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: sectionresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE sectionresultvalueannotations ( @@ -3220,7 +3221,7 @@ ALTER SEQUENCE sectionresultvalueannotations_bridgeid_seq OWNED BY sectionresult -- -- TOC entry 397 (class 1259 OID 70978) --- Name: sectionresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: sectionresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE sectionresultvalues ( @@ -3267,7 +3268,7 @@ ALTER SEQUENCE sectionresultvalues_valueid_seq OWNED BY sectionresultvalues.valu -- -- TOC entry 426 (class 1259 OID 71128) --- Name: simulations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: simulations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE simulations ( @@ -3310,7 +3311,7 @@ ALTER SEQUENCE simulations_simulationid_seq OWNED BY simulations.simulationid; -- -- TOC entry 412 (class 1259 OID 71059) --- Name: sites; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: sites; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE sites ( @@ -3324,7 +3325,7 @@ CREATE TABLE sites ( -- -- TOC entry 413 (class 1259 OID 71064) --- Name: spatialoffsets; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: spatialoffsets; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE spatialoffsets ( @@ -3341,7 +3342,7 @@ CREATE TABLE spatialoffsets ( -- -- TOC entry 354 (class 1259 OID 70775) --- Name: spatialreferenceexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: spatialreferenceexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE spatialreferenceexternalidentifiers ( @@ -3377,7 +3378,7 @@ ALTER SEQUENCE spatialreferenceexternalidentifiers_bridgeid_seq OWNED BY spatial -- -- TOC entry 415 (class 1259 OID 71071) --- Name: spatialreferences; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: spatialreferences; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE spatialreferences ( @@ -3439,7 +3440,7 @@ CREATE VIEW specimen_site_sf AS -- -- TOC entry 363 (class 1259 OID 70825) --- Name: specimenbatchpostions; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: specimenbatchpostions; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE specimenbatchpostions ( @@ -3451,7 +3452,7 @@ CREATE TABLE specimenbatchpostions ( -- -- TOC entry 416 (class 1259 OID 71080) --- Name: specimens; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: specimens; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE specimens ( @@ -3464,7 +3465,7 @@ CREATE TABLE specimens ( -- -- TOC entry 418 (class 1259 OID 71090) --- Name: specimentaxonomicclassifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: specimentaxonomicclassifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE specimentaxonomicclassifiers ( @@ -3499,7 +3500,7 @@ ALTER SEQUENCE specimentaxonomicclassifiers_bridgeid_seq OWNED BY specimentaxono -- -- TOC entry 398 (class 1259 OID 70987) --- Name: spectraresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: spectraresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE spectraresults ( @@ -3519,7 +3520,7 @@ CREATE TABLE spectraresults ( -- -- TOC entry 233 (class 1259 OID 70080) --- Name: spectraresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: spectraresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE spectraresultvalueannotations ( @@ -3553,7 +3554,7 @@ ALTER SEQUENCE spectraresultvalueannotations_bridgeid_seq OWNED BY spectraresult -- -- TOC entry 400 (class 1259 OID 70994) --- Name: spectraresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: spectraresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE spectraresultvalues ( @@ -3596,7 +3597,7 @@ ALTER SEQUENCE spectraresultvalues_valueid_seq OWNED BY spectraresultvalues.valu -- -- TOC entry 356 (class 1259 OID 70786) --- Name: taxonomicclassifierexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: taxonomicclassifierexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE taxonomicclassifierexternalidentifiers ( @@ -3632,7 +3633,7 @@ ALTER SEQUENCE taxonomicclassifierexternalidentifiers_bridgeid_seq OWNED BY taxo -- -- TOC entry 266 (class 1259 OID 70244) --- Name: taxonomicclassifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: taxonomicclassifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE taxonomicclassifiers ( @@ -3647,7 +3648,7 @@ CREATE TABLE taxonomicclassifiers ( -- -- TOC entry 401 (class 1259 OID 71003) --- Name: timeseriesresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: timeseriesresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE timeseriesresults ( @@ -3667,7 +3668,7 @@ CREATE TABLE timeseriesresults ( -- -- TOC entry 235 (class 1259 OID 70088) --- Name: timeseriesresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: timeseriesresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE timeseriesresultvalueannotations ( @@ -3701,7 +3702,7 @@ ALTER SEQUENCE timeseriesresultvalueannotations_bridgeid_seq OWNED BY timeseries -- -- TOC entry 403 (class 1259 OID 71010) --- Name: timeseriesresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: timeseriesresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE timeseriesresultvalues ( @@ -3741,7 +3742,7 @@ ALTER SEQUENCE timeseriesresultvalues_valueid_seq OWNED BY timeseriesresultvalue -- -- TOC entry 404 (class 1259 OID 71019) --- Name: trajectoryresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: trajectoryresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE trajectoryresults ( @@ -3757,7 +3758,7 @@ CREATE TABLE trajectoryresults ( -- -- TOC entry 237 (class 1259 OID 70096) --- Name: trajectoryresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: trajectoryresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE trajectoryresultvalueannotations ( @@ -3791,7 +3792,7 @@ ALTER SEQUENCE trajectoryresultvalueannotations_bridgeid_seq OWNED BY trajectory -- -- TOC entry 406 (class 1259 OID 71026) --- Name: trajectoryresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: trajectoryresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE trajectoryresultvalues ( @@ -3840,7 +3841,7 @@ ALTER SEQUENCE trajectoryresultvalues_valueid_seq OWNED BY trajectoryresultvalue -- -- TOC entry 407 (class 1259 OID 71035) --- Name: transectresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: transectresults; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE transectresults ( @@ -3858,7 +3859,7 @@ CREATE TABLE transectresults ( -- -- TOC entry 239 (class 1259 OID 70104) --- Name: transectresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: transectresultvalueannotations; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE transectresultvalueannotations ( @@ -3892,7 +3893,7 @@ ALTER SEQUENCE transectresultvalueannotations_bridgeid_seq OWNED BY transectresu -- -- TOC entry 409 (class 1259 OID 71042) --- Name: transectresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: transectresultvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE transectresultvalues ( @@ -3940,7 +3941,7 @@ ALTER SEQUENCE transectresultvalues_valueid_seq OWNED BY transectresultvalues.va -- -- TOC entry 268 (class 1259 OID 70254) --- Name: units; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: units; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE units ( @@ -3976,7 +3977,7 @@ ALTER SEQUENCE units_unitsid_seq OWNED BY units.unitsid; -- -- TOC entry 341 (class 1259 OID 70704) --- Name: variableextensionpropertyvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: variableextensionpropertyvalues; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE variableextensionpropertyvalues ( @@ -4011,7 +4012,7 @@ ALTER SEQUENCE variableextensionpropertyvalues_bridgeid_seq OWNED BY variableext -- -- TOC entry 358 (class 1259 OID 70797) --- Name: variableexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: variableexternalidentifiers; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE variableexternalidentifiers ( @@ -4047,7 +4048,7 @@ ALTER SEQUENCE variableexternalidentifiers_bridgeid_seq OWNED BY variableexterna -- -- TOC entry 270 (class 1259 OID 70265) --- Name: variables; Type: TABLE; Schema: odm2; Owner: -; Tablespace: +-- Name: variables; Type: TABLE; Schema: odm2; Owner: -; Tablespace: -- CREATE TABLE variables ( @@ -20697,7 +20698,7 @@ SET search_path = odm2, pg_catalog; -- -- TOC entry 4069 (class 2606 OID 69994) --- Name: actionannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: actionannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY actionannotations @@ -20706,7 +20707,7 @@ ALTER TABLE ONLY actionannotations -- -- TOC entry 4099 (class 2606 OID 70120) --- Name: actionby_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: actionby_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY actionby @@ -20715,7 +20716,7 @@ ALTER TABLE ONLY actionby -- -- TOC entry 4256 (class 2606 OID 70813) --- Name: actiondirectives_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: actiondirectives_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY actiondirectives @@ -20724,7 +20725,7 @@ ALTER TABLE ONLY actiondirectives -- -- TOC entry 4224 (class 2606 OID 70658) --- Name: actionextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: actionextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY actionextensionpropertyvalues @@ -20733,7 +20734,7 @@ ALTER TABLE ONLY actionextensionpropertyvalues -- -- TOC entry 4101 (class 2606 OID 70131) --- Name: actions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: actions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY actions @@ -20742,7 +20743,7 @@ ALTER TABLE ONLY actions -- -- TOC entry 4103 (class 2606 OID 70142) --- Name: affiliations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: affiliations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY affiliations @@ -20751,7 +20752,7 @@ ALTER TABLE ONLY affiliations -- -- TOC entry 4071 (class 2606 OID 70005) --- Name: annotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: annotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY annotations @@ -20760,7 +20761,7 @@ ALTER TABLE ONLY annotations -- -- TOC entry 4262 (class 2606 OID 70837) --- Name: authorlists_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: authorlists_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY authorlists @@ -20769,7 +20770,7 @@ ALTER TABLE ONLY authorlists -- -- TOC entry 4200 (class 2606 OID 70544) --- Name: calibrationactions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: calibrationactions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY calibrationactions @@ -20778,7 +20779,7 @@ ALTER TABLE ONLY calibrationactions -- -- TOC entry 4202 (class 2606 OID 70552) --- Name: calibrationreferenceequipment_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: calibrationreferenceequipment_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY calibrationreferenceequipment @@ -20787,7 +20788,7 @@ ALTER TABLE ONLY calibrationreferenceequipment -- -- TOC entry 4204 (class 2606 OID 70560) --- Name: calibrationstandards_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: calibrationstandards_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY calibrationstandards @@ -20796,7 +20797,7 @@ ALTER TABLE ONLY calibrationstandards -- -- TOC entry 4282 (class 2606 OID 70914) --- Name: categoricalresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: categoricalresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY categoricalresults @@ -20805,7 +20806,7 @@ ALTER TABLE ONLY categoricalresults -- -- TOC entry 4073 (class 2606 OID 70013) --- Name: categoricalresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: categoricalresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY categoricalresultvalueannotations @@ -20814,7 +20815,7 @@ ALTER TABLE ONLY categoricalresultvalueannotations -- -- TOC entry 4284 (class 2606 OID 70922) --- Name: categoricalresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: categoricalresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY categoricalresultvalues @@ -20823,7 +20824,7 @@ ALTER TABLE ONLY categoricalresultvalues -- -- TOC entry 4226 (class 2606 OID 70666) --- Name: citationextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: citationextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY citationextensionpropertyvalues @@ -20832,7 +20833,7 @@ ALTER TABLE ONLY citationextensionpropertyvalues -- -- TOC entry 4238 (class 2606 OID 70720) --- Name: citationexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: citationexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY citationexternalidentifiers @@ -20841,7 +20842,7 @@ ALTER TABLE ONLY citationexternalidentifiers -- -- TOC entry 4264 (class 2606 OID 70848) --- Name: citations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: citations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY citations @@ -20850,7 +20851,7 @@ ALTER TABLE ONLY citations -- -- TOC entry 4132 (class 2606 OID 70281) --- Name: cv_actiontype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_actiontype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_actiontype @@ -20859,7 +20860,7 @@ ALTER TABLE ONLY cv_actiontype -- -- TOC entry 4134 (class 2606 OID 70289) --- Name: cv_aggregationstatistic_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_aggregationstatistic_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_aggregationstatistic @@ -20868,7 +20869,7 @@ ALTER TABLE ONLY cv_aggregationstatistic -- -- TOC entry 4136 (class 2606 OID 70297) --- Name: cv_annotationtype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_annotationtype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_annotationtype @@ -20877,7 +20878,7 @@ ALTER TABLE ONLY cv_annotationtype -- -- TOC entry 4138 (class 2606 OID 70305) --- Name: cv_censorcode_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_censorcode_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_censorcode @@ -20886,7 +20887,7 @@ ALTER TABLE ONLY cv_censorcode -- -- TOC entry 4140 (class 2606 OID 70313) --- Name: cv_dataqualitytype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_dataqualitytype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_dataqualitytype @@ -20895,7 +20896,7 @@ ALTER TABLE ONLY cv_dataqualitytype -- -- TOC entry 4142 (class 2606 OID 70321) --- Name: cv_datasettypecv_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_datasettypecv_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_datasettypecv @@ -20904,7 +20905,7 @@ ALTER TABLE ONLY cv_datasettypecv -- -- TOC entry 4144 (class 2606 OID 70329) --- Name: cv_directivetype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_directivetype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_directivetype @@ -20913,7 +20914,7 @@ ALTER TABLE ONLY cv_directivetype -- -- TOC entry 4146 (class 2606 OID 70337) --- Name: cv_elevationdatum_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_elevationdatum_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_elevationdatum @@ -20922,7 +20923,7 @@ ALTER TABLE ONLY cv_elevationdatum -- -- TOC entry 4148 (class 2606 OID 70345) --- Name: cv_equipmenttype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_equipmenttype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_equipmenttype @@ -20931,7 +20932,7 @@ ALTER TABLE ONLY cv_equipmenttype -- -- TOC entry 4150 (class 2606 OID 70353) --- Name: cv_methodtype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_methodtype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_methodtype @@ -20940,7 +20941,7 @@ ALTER TABLE ONLY cv_methodtype -- -- TOC entry 4152 (class 2606 OID 70361) --- Name: cv_organizationtype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_organizationtype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_organizationtype @@ -20949,7 +20950,7 @@ ALTER TABLE ONLY cv_organizationtype -- -- TOC entry 4154 (class 2606 OID 70369) --- Name: cv_propertydatatype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_propertydatatype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_propertydatatype @@ -20958,7 +20959,7 @@ ALTER TABLE ONLY cv_propertydatatype -- -- TOC entry 4156 (class 2606 OID 70377) --- Name: cv_qualitycode_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_qualitycode_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_qualitycode @@ -20967,7 +20968,7 @@ ALTER TABLE ONLY cv_qualitycode -- -- TOC entry 4158 (class 2606 OID 70385) --- Name: cv_referencematerialmedium_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_referencematerialmedium_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_referencematerialmedium @@ -20976,7 +20977,7 @@ ALTER TABLE ONLY cv_referencematerialmedium -- -- TOC entry 4160 (class 2606 OID 70393) --- Name: cv_relationshiptype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_relationshiptype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_relationshiptype @@ -20985,7 +20986,7 @@ ALTER TABLE ONLY cv_relationshiptype -- -- TOC entry 4162 (class 2606 OID 70401) --- Name: cv_resulttype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_resulttype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_resulttype @@ -20994,7 +20995,7 @@ ALTER TABLE ONLY cv_resulttype -- -- TOC entry 4164 (class 2606 OID 70409) --- Name: cv_sampledmedium_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_sampledmedium_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_sampledmedium @@ -21003,7 +21004,7 @@ ALTER TABLE ONLY cv_sampledmedium -- -- TOC entry 4166 (class 2606 OID 70417) --- Name: cv_samplingfeaturegeotype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_samplingfeaturegeotype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_samplingfeaturegeotype @@ -21012,7 +21013,7 @@ ALTER TABLE ONLY cv_samplingfeaturegeotype -- -- TOC entry 4168 (class 2606 OID 70425) --- Name: cv_samplingfeaturetype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_samplingfeaturetype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_samplingfeaturetype @@ -21021,7 +21022,7 @@ ALTER TABLE ONLY cv_samplingfeaturetype -- -- TOC entry 4170 (class 2606 OID 70433) --- Name: cv_sitetype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_sitetype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_sitetype @@ -21030,7 +21031,7 @@ ALTER TABLE ONLY cv_sitetype -- -- TOC entry 4172 (class 2606 OID 70441) --- Name: cv_spatialoffsettype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_spatialoffsettype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_spatialoffsettype @@ -21039,7 +21040,7 @@ ALTER TABLE ONLY cv_spatialoffsettype -- -- TOC entry 4174 (class 2606 OID 70449) --- Name: cv_speciation_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_speciation_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_speciation @@ -21048,7 +21049,7 @@ ALTER TABLE ONLY cv_speciation -- -- TOC entry 4176 (class 2606 OID 70457) --- Name: cv_specimenmedium_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_specimenmedium_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_specimenmedium @@ -21057,7 +21058,7 @@ ALTER TABLE ONLY cv_specimenmedium -- -- TOC entry 4178 (class 2606 OID 70465) --- Name: cv_specimentype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_specimentype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_specimentype @@ -21066,7 +21067,7 @@ ALTER TABLE ONLY cv_specimentype -- -- TOC entry 4180 (class 2606 OID 70473) --- Name: cv_status_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_status_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_status @@ -21075,7 +21076,7 @@ ALTER TABLE ONLY cv_status -- -- TOC entry 4182 (class 2606 OID 70481) --- Name: cv_taxonomicclassifiertype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_taxonomicclassifiertype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_taxonomicclassifiertype @@ -21084,7 +21085,7 @@ ALTER TABLE ONLY cv_taxonomicclassifiertype -- -- TOC entry 4184 (class 2606 OID 70489) --- Name: cv_unitstype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_unitstype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_unitstype @@ -21093,7 +21094,7 @@ ALTER TABLE ONLY cv_unitstype -- -- TOC entry 4186 (class 2606 OID 70497) --- Name: cv_variablename_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_variablename_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_variablename @@ -21102,7 +21103,7 @@ ALTER TABLE ONLY cv_variablename -- -- TOC entry 4188 (class 2606 OID 70505) --- Name: cv_variabletype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: cv_variabletype_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY cv_variabletype @@ -21111,7 +21112,7 @@ ALTER TABLE ONLY cv_variabletype -- -- TOC entry 4206 (class 2606 OID 70571) --- Name: dataloggerfilecolumns_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: dataloggerfilecolumns_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY dataloggerfilecolumns @@ -21120,7 +21121,7 @@ ALTER TABLE ONLY dataloggerfilecolumns -- -- TOC entry 4208 (class 2606 OID 70582) --- Name: dataloggerfiles_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: dataloggerfiles_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY dataloggerfiles @@ -21129,7 +21130,7 @@ ALTER TABLE ONLY dataloggerfiles -- -- TOC entry 4210 (class 2606 OID 70593) --- Name: dataloggerprogramfiles_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: dataloggerprogramfiles_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY dataloggerprogramfiles @@ -21138,7 +21139,7 @@ ALTER TABLE ONLY dataloggerprogramfiles -- -- TOC entry 4190 (class 2606 OID 70513) --- Name: dataquality_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: dataquality_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY dataquality @@ -21147,7 +21148,7 @@ ALTER TABLE ONLY dataquality -- -- TOC entry 4266 (class 2606 OID 70856) --- Name: datasetcitations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: datasetcitations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY datasetcitations @@ -21156,7 +21157,7 @@ ALTER TABLE ONLY datasetcitations -- -- TOC entry 4105 (class 2606 OID 70153) --- Name: datasets_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: datasets_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY datasets @@ -21165,7 +21166,7 @@ ALTER TABLE ONLY datasets -- -- TOC entry 4107 (class 2606 OID 70161) --- Name: datasetsresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: datasetsresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY datasetsresults @@ -21174,7 +21175,7 @@ ALTER TABLE ONLY datasetsresults -- -- TOC entry 4268 (class 2606 OID 70864) --- Name: derivationequations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: derivationequations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY derivationequations @@ -21183,7 +21184,7 @@ ALTER TABLE ONLY derivationequations -- -- TOC entry 4258 (class 2606 OID 70824) --- Name: directives_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: directives_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY directives @@ -21192,7 +21193,7 @@ ALTER TABLE ONLY directives -- -- TOC entry 4212 (class 2606 OID 70604) --- Name: equipment_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: equipment_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY equipment @@ -21201,7 +21202,7 @@ ALTER TABLE ONLY equipment -- -- TOC entry 4075 (class 2606 OID 70021) --- Name: equipmentannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: equipmentannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY equipmentannotations @@ -21210,7 +21211,7 @@ ALTER TABLE ONLY equipmentannotations -- -- TOC entry 4214 (class 2606 OID 70615) --- Name: equipmentmodels_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: equipmentmodels_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY equipmentmodels @@ -21219,7 +21220,7 @@ ALTER TABLE ONLY equipmentmodels -- -- TOC entry 4216 (class 2606 OID 70623) --- Name: equipmentused_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: equipmentused_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY equipmentused @@ -21228,7 +21229,7 @@ ALTER TABLE ONLY equipmentused -- -- TOC entry 4228 (class 2606 OID 70677) --- Name: extensionproperties_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: extensionproperties_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY extensionproperties @@ -21237,7 +21238,7 @@ ALTER TABLE ONLY extensionproperties -- -- TOC entry 4240 (class 2606 OID 70728) --- Name: externalidentifiersystems_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: externalidentifiersystems_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY externalidentifiersystems @@ -21246,7 +21247,7 @@ ALTER TABLE ONLY externalidentifiersystems -- -- TOC entry 4109 (class 2606 OID 70169) --- Name: featureactions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: featureactions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY featureactions @@ -21255,7 +21256,7 @@ ALTER TABLE ONLY featureactions -- -- TOC entry 4218 (class 2606 OID 70634) --- Name: instrumentoutputvariables_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: instrumentoutputvariables_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY instrumentoutputvariables @@ -21264,7 +21265,7 @@ ALTER TABLE ONLY instrumentoutputvariables -- -- TOC entry 4220 (class 2606 OID 70642) --- Name: maintenanceactions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: maintenanceactions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY maintenanceactions @@ -21273,7 +21274,7 @@ ALTER TABLE ONLY maintenanceactions -- -- TOC entry 4286 (class 2606 OID 70930) --- Name: measurementresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: measurementresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY measurementresults @@ -21282,7 +21283,7 @@ ALTER TABLE ONLY measurementresults -- -- TOC entry 4077 (class 2606 OID 70029) --- Name: measurementresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: measurementresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY measurementresultvalueannotations @@ -21291,7 +21292,7 @@ ALTER TABLE ONLY measurementresultvalueannotations -- -- TOC entry 4288 (class 2606 OID 70938) --- Name: measurementresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: measurementresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY measurementresultvalues @@ -21300,7 +21301,7 @@ ALTER TABLE ONLY measurementresultvalues -- -- TOC entry 4079 (class 2606 OID 70037) --- Name: methodannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: methodannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY methodannotations @@ -21309,7 +21310,7 @@ ALTER TABLE ONLY methodannotations -- -- TOC entry 4270 (class 2606 OID 70872) --- Name: methodcitations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: methodcitations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY methodcitations @@ -21318,7 +21319,7 @@ ALTER TABLE ONLY methodcitations -- -- TOC entry 4230 (class 2606 OID 70685) --- Name: methodextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: methodextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY methodextensionpropertyvalues @@ -21327,7 +21328,7 @@ ALTER TABLE ONLY methodextensionpropertyvalues -- -- TOC entry 4242 (class 2606 OID 70739) --- Name: methodexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: methodexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY methodexternalidentifiers @@ -21336,7 +21337,7 @@ ALTER TABLE ONLY methodexternalidentifiers -- -- TOC entry 4111 (class 2606 OID 70180) --- Name: methods_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: methods_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY methods @@ -21345,7 +21346,7 @@ ALTER TABLE ONLY methods -- -- TOC entry 4330 (class 2606 OID 71106) --- Name: modelaffiliations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: modelaffiliations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY modelaffiliations @@ -21354,7 +21355,7 @@ ALTER TABLE ONLY modelaffiliations -- -- TOC entry 4332 (class 2606 OID 71117) --- Name: models_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: models_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY models @@ -21363,7 +21364,7 @@ ALTER TABLE ONLY models -- -- TOC entry 4113 (class 2606 OID 70191) --- Name: organizations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: organizations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY organizations @@ -21372,7 +21373,7 @@ ALTER TABLE ONLY organizations -- -- TOC entry 4115 (class 2606 OID 70202) --- Name: people_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: people_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY people @@ -21381,7 +21382,7 @@ ALTER TABLE ONLY people -- -- TOC entry 4244 (class 2606 OID 70750) --- Name: personexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: personexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY personexternalidentifiers @@ -21390,7 +21391,7 @@ ALTER TABLE ONLY personexternalidentifiers -- -- TOC entry 4290 (class 2606 OID 70943) --- Name: pointcoverageresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: pointcoverageresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY pointcoverageresults @@ -21399,7 +21400,7 @@ ALTER TABLE ONLY pointcoverageresults -- -- TOC entry 4081 (class 2606 OID 70045) --- Name: pointcoverageresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: pointcoverageresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY pointcoverageresultvalueannotations @@ -21408,7 +21409,7 @@ ALTER TABLE ONLY pointcoverageresultvalueannotations -- -- TOC entry 4292 (class 2606 OID 70954) --- Name: pointcoverageresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: pointcoverageresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY pointcoverageresultvalues @@ -21417,7 +21418,7 @@ ALTER TABLE ONLY pointcoverageresultvalues -- -- TOC entry 4117 (class 2606 OID 70213) --- Name: processinglevels_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: processinglevels_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY processinglevels @@ -21426,7 +21427,7 @@ ALTER TABLE ONLY processinglevels -- -- TOC entry 4294 (class 2606 OID 70959) --- Name: profileresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: profileresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY profileresults @@ -21435,7 +21436,7 @@ ALTER TABLE ONLY profileresults -- -- TOC entry 4083 (class 2606 OID 70053) --- Name: profileresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: profileresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY profileresultvalueannotations @@ -21444,7 +21445,7 @@ ALTER TABLE ONLY profileresultvalueannotations -- -- TOC entry 4296 (class 2606 OID 70970) --- Name: profileresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: profileresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY profileresultvalues @@ -21453,7 +21454,7 @@ ALTER TABLE ONLY profileresultvalues -- -- TOC entry 4246 (class 2606 OID 70761) --- Name: referencematerialexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: referencematerialexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY referencematerialexternalidentifiers @@ -21462,7 +21463,7 @@ ALTER TABLE ONLY referencematerialexternalidentifiers -- -- TOC entry 4192 (class 2606 OID 70521) --- Name: referencematerials_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: referencematerials_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY referencematerials @@ -21471,7 +21472,7 @@ ALTER TABLE ONLY referencematerials -- -- TOC entry 4194 (class 2606 OID 70526) --- Name: referencematerialvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: referencematerialvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY referencematerialvalues @@ -21480,7 +21481,7 @@ ALTER TABLE ONLY referencematerialvalues -- -- TOC entry 4119 (class 2606 OID 70221) --- Name: relatedactions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedactions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY relatedactions @@ -21489,7 +21490,7 @@ ALTER TABLE ONLY relatedactions -- -- TOC entry 4272 (class 2606 OID 70880) --- Name: relatedannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY relatedannotations @@ -21498,7 +21499,7 @@ ALTER TABLE ONLY relatedannotations -- -- TOC entry 4274 (class 2606 OID 70888) --- Name: relatedcitations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedcitations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY relatedcitations @@ -21507,7 +21508,7 @@ ALTER TABLE ONLY relatedcitations -- -- TOC entry 4276 (class 2606 OID 70896) --- Name: relateddatasets_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: relateddatasets_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY relateddatasets @@ -21516,7 +21517,7 @@ ALTER TABLE ONLY relateddatasets -- -- TOC entry 4222 (class 2606 OID 70650) --- Name: relatedequipment_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedequipment_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY relatedequipment @@ -21525,7 +21526,7 @@ ALTER TABLE ONLY relatedequipment -- -- TOC entry 4318 (class 2606 OID 71058) --- Name: relatedfeatures_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedfeatures_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY relatedfeatures @@ -21534,7 +21535,7 @@ ALTER TABLE ONLY relatedfeatures -- -- TOC entry 4334 (class 2606 OID 71125) --- Name: relatedmodels_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedmodels_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY relatedmodels @@ -21543,7 +21544,7 @@ ALTER TABLE ONLY relatedmodels -- -- TOC entry 4278 (class 2606 OID 70904) --- Name: relatedresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: relatedresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY relatedresults @@ -21552,7 +21553,7 @@ ALTER TABLE ONLY relatedresults -- -- TOC entry 4085 (class 2606 OID 70061) --- Name: resultannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: resultannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY resultannotations @@ -21561,7 +21562,7 @@ ALTER TABLE ONLY resultannotations -- -- TOC entry 4280 (class 2606 OID 70909) --- Name: resultderivationequations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: resultderivationequations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY resultderivationequations @@ -21570,7 +21571,7 @@ ALTER TABLE ONLY resultderivationequations -- -- TOC entry 4232 (class 2606 OID 70693) --- Name: resultextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: resultextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY resultextensionpropertyvalues @@ -21579,7 +21580,7 @@ ALTER TABLE ONLY resultextensionpropertyvalues -- -- TOC entry 4196 (class 2606 OID 70531) --- Name: resultnormalizationvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: resultnormalizationvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY resultnormalizationvalues @@ -21588,7 +21589,7 @@ ALTER TABLE ONLY resultnormalizationvalues -- -- TOC entry 4121 (class 2606 OID 70232) --- Name: results_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: results_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY results @@ -21597,7 +21598,7 @@ ALTER TABLE ONLY results -- -- TOC entry 4198 (class 2606 OID 70539) --- Name: resultsdataquality_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: resultsdataquality_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY resultsdataquality @@ -21606,7 +21607,7 @@ ALTER TABLE ONLY resultsdataquality -- -- TOC entry 4087 (class 2606 OID 70069) --- Name: samplingfeatureannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: samplingfeatureannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY samplingfeatureannotations @@ -21615,7 +21616,7 @@ ALTER TABLE ONLY samplingfeatureannotations -- -- TOC entry 4234 (class 2606 OID 70701) --- Name: samplingfeatureextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: samplingfeatureextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY samplingfeatureextensionpropertyvalues @@ -21624,7 +21625,7 @@ ALTER TABLE ONLY samplingfeatureextensionpropertyvalues -- -- TOC entry 4248 (class 2606 OID 70772) --- Name: samplingfeatureexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: samplingfeatureexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY samplingfeatureexternalidentifiers @@ -21633,7 +21634,7 @@ ALTER TABLE ONLY samplingfeatureexternalidentifiers -- -- TOC entry 4124 (class 2606 OID 70243) --- Name: samplingfeatures_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: samplingfeatures_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY samplingfeatures @@ -21642,7 +21643,7 @@ ALTER TABLE ONLY samplingfeatures -- -- TOC entry 4298 (class 2606 OID 70975) --- Name: sectionresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: sectionresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY sectionresults @@ -21651,7 +21652,7 @@ ALTER TABLE ONLY sectionresults -- -- TOC entry 4089 (class 2606 OID 70077) --- Name: sectionresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: sectionresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY sectionresultvalueannotations @@ -21660,7 +21661,7 @@ ALTER TABLE ONLY sectionresultvalueannotations -- -- TOC entry 4300 (class 2606 OID 70986) --- Name: sectionresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: sectionresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY sectionresultvalues @@ -21669,7 +21670,7 @@ ALTER TABLE ONLY sectionresultvalues -- -- TOC entry 4336 (class 2606 OID 71136) --- Name: simulations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: simulations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY simulations @@ -21678,7 +21679,7 @@ ALTER TABLE ONLY simulations -- -- TOC entry 4320 (class 2606 OID 71063) --- Name: sites_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: sites_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY sites @@ -21687,7 +21688,7 @@ ALTER TABLE ONLY sites -- -- TOC entry 4322 (class 2606 OID 71068) --- Name: spatialoffsets_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: spatialoffsets_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY spatialoffsets @@ -21696,7 +21697,7 @@ ALTER TABLE ONLY spatialoffsets -- -- TOC entry 4250 (class 2606 OID 70783) --- Name: spatialreferenceexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: spatialreferenceexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY spatialreferenceexternalidentifiers @@ -21705,7 +21706,7 @@ ALTER TABLE ONLY spatialreferenceexternalidentifiers -- -- TOC entry 4324 (class 2606 OID 71079) --- Name: spatialreferences_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: spatialreferences_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY spatialreferences @@ -21714,7 +21715,7 @@ ALTER TABLE ONLY spatialreferences -- -- TOC entry 4260 (class 2606 OID 70829) --- Name: specimenbatchpostions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: specimenbatchpostions_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY specimenbatchpostions @@ -21723,7 +21724,7 @@ ALTER TABLE ONLY specimenbatchpostions -- -- TOC entry 4326 (class 2606 OID 71087) --- Name: specimens_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: specimens_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY specimens @@ -21732,7 +21733,7 @@ ALTER TABLE ONLY specimens -- -- TOC entry 4328 (class 2606 OID 71095) --- Name: specimentaxonomicclassifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: specimentaxonomicclassifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY specimentaxonomicclassifiers @@ -21741,7 +21742,7 @@ ALTER TABLE ONLY specimentaxonomicclassifiers -- -- TOC entry 4302 (class 2606 OID 70991) --- Name: spectraresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: spectraresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY spectraresults @@ -21750,7 +21751,7 @@ ALTER TABLE ONLY spectraresults -- -- TOC entry 4091 (class 2606 OID 70085) --- Name: spectraresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: spectraresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY spectraresultvalueannotations @@ -21759,7 +21760,7 @@ ALTER TABLE ONLY spectraresultvalueannotations -- -- TOC entry 4304 (class 2606 OID 71002) --- Name: spectraresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: spectraresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY spectraresultvalues @@ -21768,7 +21769,7 @@ ALTER TABLE ONLY spectraresultvalues -- -- TOC entry 4252 (class 2606 OID 70794) --- Name: taxonomicclassifierexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: taxonomicclassifierexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY taxonomicclassifierexternalidentifiers @@ -21777,7 +21778,7 @@ ALTER TABLE ONLY taxonomicclassifierexternalidentifiers -- -- TOC entry 4126 (class 2606 OID 70251) --- Name: taxonomicclassifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: taxonomicclassifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY taxonomicclassifiers @@ -21786,7 +21787,7 @@ ALTER TABLE ONLY taxonomicclassifiers -- -- TOC entry 4306 (class 2606 OID 71007) --- Name: timeseriesresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: timeseriesresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY timeseriesresults @@ -21795,7 +21796,7 @@ ALTER TABLE ONLY timeseriesresults -- -- TOC entry 4093 (class 2606 OID 70093) --- Name: timeseriesresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: timeseriesresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY timeseriesresultvalueannotations @@ -21804,7 +21805,7 @@ ALTER TABLE ONLY timeseriesresultvalueannotations -- -- TOC entry 4308 (class 2606 OID 71018) --- Name: timeseriesresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: timeseriesresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY timeseriesresultvalues @@ -21813,7 +21814,7 @@ ALTER TABLE ONLY timeseriesresultvalues -- -- TOC entry 4310 (class 2606 OID 71023) --- Name: trajectoryresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: trajectoryresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY trajectoryresults @@ -21822,7 +21823,7 @@ ALTER TABLE ONLY trajectoryresults -- -- TOC entry 4095 (class 2606 OID 70101) --- Name: trajectoryresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: trajectoryresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY trajectoryresultvalueannotations @@ -21831,7 +21832,7 @@ ALTER TABLE ONLY trajectoryresultvalueannotations -- -- TOC entry 4312 (class 2606 OID 71034) --- Name: trajectoryresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: trajectoryresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY trajectoryresultvalues @@ -21840,7 +21841,7 @@ ALTER TABLE ONLY trajectoryresultvalues -- -- TOC entry 4314 (class 2606 OID 71039) --- Name: transectresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: transectresults_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY transectresults @@ -21849,7 +21850,7 @@ ALTER TABLE ONLY transectresults -- -- TOC entry 4097 (class 2606 OID 70109) --- Name: transectresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: transectresultvalueannotations_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY transectresultvalueannotations @@ -21858,7 +21859,7 @@ ALTER TABLE ONLY transectresultvalueannotations -- -- TOC entry 4316 (class 2606 OID 71050) --- Name: transectresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: transectresultvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY transectresultvalues @@ -21867,7 +21868,7 @@ ALTER TABLE ONLY transectresultvalues -- -- TOC entry 4128 (class 2606 OID 70262) --- Name: units_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: units_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY units @@ -21876,7 +21877,7 @@ ALTER TABLE ONLY units -- -- TOC entry 4236 (class 2606 OID 70709) --- Name: variableextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: variableextensionpropertyvalues_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY variableextensionpropertyvalues @@ -21885,7 +21886,7 @@ ALTER TABLE ONLY variableextensionpropertyvalues -- -- TOC entry 4254 (class 2606 OID 70805) --- Name: variableexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: variableexternalidentifiers_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY variableexternalidentifiers @@ -21894,7 +21895,7 @@ ALTER TABLE ONLY variableexternalidentifiers -- -- TOC entry 4130 (class 2606 OID 70273) --- Name: variables_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: +-- Name: variables_pkey; Type: CONSTRAINT; Schema: odm2; Owner: -; Tablespace: -- ALTER TABLE ONLY variables @@ -21903,7 +21904,7 @@ ALTER TABLE ONLY variables -- -- TOC entry 4122 (class 1259 OID 72583) --- Name: idx_samplingfeature_featuregeom; Type: INDEX; Schema: odm2; Owner: -; Tablespace: +-- Name: idx_samplingfeature_featuregeom; Type: INDEX; Schema: odm2; Owner: -; Tablespace: -- CREATE INDEX idx_samplingfeature_featuregeom ON samplingfeatures USING gist (featuregeometry); diff --git a/versioneer.py b/versioneer.py new file mode 100644 index 0000000..64fea1c --- /dev/null +++ b/versioneer.py @@ -0,0 +1,1822 @@ + +# Version: 0.18 + +"""The Versioneer - like a rocketeer, but for versions. + +The Versioneer +============== + +* like a rocketeer, but for versions! +* https://github.com/warner/python-versioneer +* Brian Warner +* License: Public Domain +* Compatible With: python2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, and pypy +* [![Latest Version] +(https://pypip.in/version/versioneer/badge.svg?style=flat) +](https://pypi.python.org/pypi/versioneer/) +* [![Build Status] +(https://travis-ci.org/warner/python-versioneer.png?branch=master) +](https://travis-ci.org/warner/python-versioneer) + +This is a tool for managing a recorded version number in distutils-based +python projects. The goal is to remove the tedious and error-prone "update +the embedded version string" step from your release process. Making a new +release should be as easy as recording a new tag in your version-control +system, and maybe making new tarballs. + + +## Quick Install + +* `pip install versioneer` to somewhere to your $PATH +* add a `[versioneer]` section to your setup.cfg (see below) +* run `versioneer install` in your source tree, commit the results + +## Version Identifiers + +Source trees come from a variety of places: + +* a version-control system checkout (mostly used by developers) +* a nightly tarball, produced by build automation +* a snapshot tarball, produced by a web-based VCS browser, like github's + "tarball from tag" feature +* a release tarball, produced by "setup.py sdist", distributed through PyPI + +Within each source tree, the version identifier (either a string or a number, +this tool is format-agnostic) can come from a variety of places: + +* ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows + about recent "tags" and an absolute revision-id +* the name of the directory into which the tarball was unpacked +* an expanded VCS keyword ($Id$, etc) +* a `_version.py` created by some earlier build step + +For released software, the version identifier is closely related to a VCS +tag. Some projects use tag names that include more than just the version +string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool +needs to strip the tag prefix to extract the version identifier. For +unreleased software (between tags), the version identifier should provide +enough information to help developers recreate the same tree, while also +giving them an idea of roughly how old the tree is (after version 1.2, before +version 1.3). Many VCS systems can report a description that captures this, +for example `git describe --tags --dirty --always` reports things like +"0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the +0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has +uncommitted changes. + +The version identifier is used for multiple purposes: + +* to allow the module to self-identify its version: `myproject.__version__` +* to choose a name and prefix for a 'setup.py sdist' tarball + +## Theory of Operation + +Versioneer works by adding a special `_version.py` file into your source +tree, where your `__init__.py` can import it. This `_version.py` knows how to +dynamically ask the VCS tool for version information at import time. + +`_version.py` also contains `$Revision$` markers, and the installation +process marks `_version.py` to have this marker rewritten with a tag name +during the `git archive` command. As a result, generated tarballs will +contain enough information to get the proper version. + +To allow `setup.py` to compute a version too, a `versioneer.py` is added to +the top level of your source tree, next to `setup.py` and the `setup.cfg` +that configures it. This overrides several distutils/setuptools commands to +compute the version when invoked, and changes `setup.py build` and `setup.py +sdist` to replace `_version.py` with a small static file that contains just +the generated version data. + +## Installation + +See [INSTALL.md](./INSTALL.md) for detailed installation instructions. + +## Version-String Flavors + +Code which uses Versioneer can learn about its version string at runtime by +importing `_version` from your main `__init__.py` file and running the +`get_versions()` function. From the "outside" (e.g. in `setup.py`), you can +import the top-level `versioneer.py` and run `get_versions()`. + +Both functions return a dictionary with different flavors of version +information: + +* `['version']`: A condensed version string, rendered using the selected + style. This is the most commonly used value for the project's version + string. The default "pep440" style yields strings like `0.11`, + `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section + below for alternative styles. + +* `['full-revisionid']`: detailed revision identifier. For Git, this is the + full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". + +* `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the + commit date in ISO 8601 format. This will be None if the date is not + available. + +* `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that + this is only accurate if run in a VCS checkout, otherwise it is likely to + be False or None + +* `['error']`: if the version string could not be computed, this will be set + to a string describing the problem, otherwise it will be None. It may be + useful to throw an exception in setup.py if this is set, to avoid e.g. + creating tarballs with a version string of "unknown". + +Some variants are more useful than others. Including `full-revisionid` in a +bug report should allow developers to reconstruct the exact code being tested +(or indicate the presence of local changes that should be shared with the +developers). `version` is suitable for display in an "about" box or a CLI +`--version` output: it can be easily compared against release notes and lists +of bugs fixed in various releases. + +The installer adds the following text to your `__init__.py` to place a basic +version in `YOURPROJECT.__version__`: + + from ._version import get_versions + __version__ = get_versions()['version'] + del get_versions + +## Styles + +The setup.cfg `style=` configuration controls how the VCS information is +rendered into a version string. + +The default style, "pep440", produces a PEP440-compliant string, equal to the +un-prefixed tag name for actual releases, and containing an additional "local +version" section with more detail for in-between builds. For Git, this is +TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags +--dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the +tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and +that this commit is two revisions ("+2") beyond the "0.11" tag. For released +software (exactly equal to a known tag), the identifier will only contain the +stripped tag, e.g. "0.11". + +Other styles are available. See [details.md](details.md) in the Versioneer +source tree for descriptions. + +## Debugging + +Versioneer tries to avoid fatal errors: if something goes wrong, it will tend +to return a version of "0+unknown". To investigate the problem, run `setup.py +version`, which will run the version-lookup code in a verbose mode, and will +display the full contents of `get_versions()` (including the `error` string, +which may help identify what went wrong). + +## Known Limitations + +Some situations are known to cause problems for Versioneer. This details the +most significant ones. More can be found on Github +[issues page](https://github.com/warner/python-versioneer/issues). + +### Subprojects + +Versioneer has limited support for source trees in which `setup.py` is not in +the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are +two common reasons why `setup.py` might not be in the root: + +* Source trees which contain multiple subprojects, such as + [Buildbot](https://github.com/buildbot/buildbot), which contains both + "master" and "slave" subprojects, each with their own `setup.py`, + `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI + distributions (and upload multiple independently-installable tarballs). +* Source trees whose main purpose is to contain a C library, but which also + provide bindings to Python (and perhaps other langauges) in subdirectories. + +Versioneer will look for `.git` in parent directories, and most operations +should get the right version string. However `pip` and `setuptools` have bugs +and implementation details which frequently cause `pip install .` from a +subproject directory to fail to find a correct version string (so it usually +defaults to `0+unknown`). + +`pip install --editable .` should work correctly. `setup.py install` might +work too. + +Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in +some later version. + +[Bug #38](https://github.com/warner/python-versioneer/issues/38) is tracking +this issue. The discussion in +[PR #61](https://github.com/warner/python-versioneer/pull/61) describes the +issue from the Versioneer side in more detail. +[pip PR#3176](https://github.com/pypa/pip/pull/3176) and +[pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve +pip to let Versioneer work correctly. + +Versioneer-0.16 and earlier only looked for a `.git` directory next to the +`setup.cfg`, so subprojects were completely unsupported with those releases. + +### Editable installs with setuptools <= 18.5 + +`setup.py develop` and `pip install --editable .` allow you to install a +project into a virtualenv once, then continue editing the source code (and +test) without re-installing after every change. + +"Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a +convenient way to specify executable scripts that should be installed along +with the python package. + +These both work as expected when using modern setuptools. When using +setuptools-18.5 or earlier, however, certain operations will cause +`pkg_resources.DistributionNotFound` errors when running the entrypoint +script, which must be resolved by re-installing the package. This happens +when the install happens with one version, then the egg_info data is +regenerated while a different version is checked out. Many setup.py commands +cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into +a different virtualenv), so this can be surprising. + +[Bug #83](https://github.com/warner/python-versioneer/issues/83) describes +this one, but upgrading to a newer version of setuptools should probably +resolve it. + +### Unicode version strings + +While Versioneer works (and is continually tested) with both Python 2 and +Python 3, it is not entirely consistent with bytes-vs-unicode distinctions. +Newer releases probably generate unicode version strings on py2. It's not +clear that this is wrong, but it may be surprising for applications when then +write these strings to a network connection or include them in bytes-oriented +APIs like cryptographic checksums. + +[Bug #71](https://github.com/warner/python-versioneer/issues/71) investigates +this question. + + +## Updating Versioneer + +To upgrade your project to a new release of Versioneer, do the following: + +* install the new Versioneer (`pip install -U versioneer` or equivalent) +* edit `setup.cfg`, if necessary, to include any new configuration settings + indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details. +* re-run `versioneer install` in your source tree, to replace + `SRC/_version.py` +* commit any changed files + +## Future Directions + +This tool is designed to make it easily extended to other version-control +systems: all VCS-specific components are in separate directories like +src/git/ . The top-level `versioneer.py` script is assembled from these +components by running make-versioneer.py . In the future, make-versioneer.py +will take a VCS name as an argument, and will construct a version of +`versioneer.py` that is specific to the given VCS. It might also take the +configuration arguments that are currently provided manually during +installation by editing setup.py . Alternatively, it might go the other +direction and include code from all supported VCS systems, reducing the +number of intermediate scripts. + + +## License + +To make Versioneer easier to embed, all its code is dedicated to the public +domain. The `_version.py` that it creates is also in the public domain. +Specifically, both are released under the Creative Commons "Public Domain +Dedication" license (CC0-1.0), as described in +https://creativecommons.org/publicdomain/zero/1.0/ . + +""" + +from __future__ import print_function +try: + import configparser +except ImportError: + import ConfigParser as configparser +import errno +import json +import os +import re +import subprocess +import sys + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + +def get_root(): + """Get the project root directory. + + We require that all commands are run from the project root, i.e. the + directory that contains setup.py, setup.cfg, and versioneer.py . + """ + root = os.path.realpath(os.path.abspath(os.getcwd())) + setup_py = os.path.join(root, "setup.py") + versioneer_py = os.path.join(root, "versioneer.py") + if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): + # allow 'python path/to/setup.py COMMAND' + root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) + setup_py = os.path.join(root, "setup.py") + versioneer_py = os.path.join(root, "versioneer.py") + if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): + err = ("Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND').") + raise VersioneerBadRootError(err) + try: + # Certain runtime workflows (setup.py install/develop in a setuptools + # tree) execute all dependencies in a single python process, so + # "versioneer" may be imported multiple times, and python's shared + # module-import table will cache the first one. So we can't use + # os.path.dirname(__file__), as that will find whichever + # versioneer.py was first imported, even in later projects. + me = os.path.realpath(os.path.abspath(__file__)) + me_dir = os.path.normcase(os.path.splitext(me)[0]) + vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) + if me_dir != vsr_dir: + print("Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(me), versioneer_py)) + except NameError: + pass + return root + + +def get_config_from_root(root): + """Read the project setup.cfg file to determine Versioneer config.""" + # This might raise EnvironmentError (if setup.cfg is missing), or + # configparser.NoSectionError (if it lacks a [versioneer] section), or + # configparser.NoOptionError (if it lacks "VCS="). See the docstring at + # the top of versioneer.py for instructions on writing your setup.cfg . + setup_cfg = os.path.join(root, "setup.cfg") + parser = configparser.SafeConfigParser() + with open(setup_cfg, "r") as f: + parser.readfp(f) + VCS = parser.get("versioneer", "VCS") # mandatory + + def get(parser, name): + if parser.has_option("versioneer", name): + return parser.get("versioneer", name) + return None + cfg = VersioneerConfig() + cfg.VCS = VCS + cfg.style = get(parser, "style") or "" + cfg.versionfile_source = get(parser, "versionfile_source") + cfg.versionfile_build = get(parser, "versionfile_build") + cfg.tag_prefix = get(parser, "tag_prefix") + if cfg.tag_prefix in ("''", '""'): + cfg.tag_prefix = "" + cfg.parentdir_prefix = get(parser, "parentdir_prefix") + cfg.verbose = get(parser, "verbose") + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +# these dictionaries contain VCS-specific tools +LONG_VERSION_PY = {} +HANDLERS = {} + + +def register_vcs_handler(vcs, method): # decorator + """Decorator to mark a method as the handler for a particular VCS.""" + def decorate(f): + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, + env=None): + """Call the given command(s).""" + assert isinstance(commands, list) + p = None + for c in commands: + try: + dispcmd = str([c] + args) + # remember shell=False, so use git.cmd on windows, not just git + p = subprocess.Popen([c] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None)) + break + except EnvironmentError: + e = sys.exc_info()[1] + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %s" % (commands,)) + return None, None + stdout = p.communicate()[0].strip() + if sys.version_info[0] >= 3: + stdout = stdout.decode() + if p.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, p.returncode + return stdout, p.returncode + + +LONG_VERSION_PY['git'] = ''' +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. Generated by +# versioneer-0.18 (https://github.com/warner/python-versioneer) + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys + + +def get_keywords(): + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" + git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" + git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + +def get_config(): + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "%(STYLE)s" + cfg.tag_prefix = "%(TAG_PREFIX)s" + cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" + cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY = {} +HANDLERS = {} + + +def register_vcs_handler(vcs, method): # decorator + """Decorator to mark a method as the handler for a particular VCS.""" + def decorate(f): + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, + env=None): + """Call the given command(s).""" + assert isinstance(commands, list) + p = None + for c in commands: + try: + dispcmd = str([c] + args) + # remember shell=False, so use git.cmd on windows, not just git + p = subprocess.Popen([c] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None)) + break + except EnvironmentError: + e = sys.exc_info()[1] + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %%s" %% dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %%s" %% (commands,)) + return None, None + stdout = p.communicate()[0].strip() + if sys.version_info[0] >= 3: + stdout = stdout.decode() + if p.returncode != 0: + if verbose: + print("unable to run %%s (error)" %% dispcmd) + print("stdout was %%s" %% stdout) + return None, p.returncode + return stdout, p.returncode + + +def versions_from_parentdir(parentdir_prefix, root, verbose): + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for i in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + else: + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %%s but none started with prefix %%s" %% + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs): + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords = {} + try: + f = open(versionfile_abs, "r") + for line in f.readlines(): + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + f.close() + except EnvironmentError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords(keywords, tag_prefix, verbose): + """Get version information from git keywords.""" + if not keywords: + raise NotThisMethod("no keywords at all, weird") + date = keywords.get("date") + if date is not None: + # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = set([r.strip() for r in refnames.strip("()").split(",")]) + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %%d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = set([r for r in refs if re.search(r'\d', r)]) + if verbose: + print("discarding '%%s', no digits" %% ",".join(refs - tags)) + if verbose: + print("likely tags: %%s" %% ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + if verbose: + print("picking %%s" %% r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=True) + if rc != 0: + if verbose: + print("Directory %%s not under git control" %% root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", + "--always", "--long", + "--match", "%%s*" %% tag_prefix], + cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparseable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%%s'" + %% describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%%s' doesn't start with prefix '%%s'" + print(fmt %% (full_tag, tag_prefix)) + pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" + %% (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], + cwd=root) + pieces["distance"] = int(count_out) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"], + cwd=root)[0].strip() + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces): + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces): + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_pre(pieces): + """TAG[.post.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post.devDISTANCE + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += ".post.dev%%d" %% pieces["distance"] + else: + # exception #1 + rendered = "0.post.dev%%d" %% pieces["distance"] + return rendered + + +def render_pep440_post(pieces): + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + return rendered + + +def render_pep440_old(pieces): + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Eexceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces): + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces): + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces, style): + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%%s'" %% style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions(): + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for i in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} +''' + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs): + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords = {} + try: + f = open(versionfile_abs, "r") + for line in f.readlines(): + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + f.close() + except EnvironmentError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords(keywords, tag_prefix, verbose): + """Get version information from git keywords.""" + if not keywords: + raise NotThisMethod("no keywords at all, weird") + date = keywords.get("date") + if date is not None: + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = set([r.strip() for r in refnames.strip("()").split(",")]) + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = set([r for r in refs if re.search(r'\d', r)]) + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=True) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", + "--always", "--long", + "--match", "%s*" % tag_prefix], + cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparseable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], + cwd=root) + pieces["distance"] = int(count_out) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], + cwd=root)[0].strip() + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def do_vcs_install(manifest_in, versionfile_source, ipy): + """Git-specific installation logic for Versioneer. + + For Git, this means creating/changing .gitattributes to mark _version.py + for export-subst keyword substitution. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + files = [manifest_in, versionfile_source] + if ipy: + files.append(ipy) + try: + me = __file__ + if me.endswith(".pyc") or me.endswith(".pyo"): + me = os.path.splitext(me)[0] + ".py" + versioneer_file = os.path.relpath(me) + except NameError: + versioneer_file = "versioneer.py" + files.append(versioneer_file) + present = False + try: + f = open(".gitattributes", "r") + for line in f.readlines(): + if line.strip().startswith(versionfile_source): + if "export-subst" in line.strip().split()[1:]: + present = True + f.close() + except EnvironmentError: + pass + if not present: + f = open(".gitattributes", "a+") + f.write("%s export-subst\n" % versionfile_source) + f.close() + files.append(".gitattributes") + run_command(GITS, ["add", "--"] + files) + + +def versions_from_parentdir(parentdir_prefix, root, verbose): + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for i in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + else: + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +SHORT_VERSION_PY = """ +# This file was generated by 'versioneer.py' (0.18) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. + +import json + +version_json = ''' +%s +''' # END VERSION_JSON + + +def get_versions(): + return json.loads(version_json) +""" + + +def versions_from_file(filename): + """Try to determine the version from _version.py if present.""" + try: + with open(filename) as f: + contents = f.read() + except EnvironmentError: + raise NotThisMethod("unable to read _version.py") + mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) + if not mo: + raise NotThisMethod("no version_json in _version.py") + return json.loads(mo.group(1)) + + +def write_to_version_file(filename, versions): + """Write the given version number to the given _version.py file.""" + os.unlink(filename) + contents = json.dumps(versions, sort_keys=True, + indent=1, separators=(",", ": ")) + with open(filename, "w") as f: + f.write(SHORT_VERSION_PY % contents) + + print("set %s to '%s'" % (filename, versions["version"])) + + +def plus_or_dot(pieces): + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces): + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_pre(pieces): + """TAG[.post.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post.devDISTANCE + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += ".post.dev%d" % pieces["distance"] + else: + # exception #1 + rendered = "0.post.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces): + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_old(pieces): + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Eexceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces): + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces): + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces, style): + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +class VersioneerBadRootError(Exception): + """The project root directory is unknown or missing key files.""" + + +def get_versions(verbose=False): + """Get the project version from whatever source is available. + + Returns dict with two keys: 'version' and 'full'. + """ + if "versioneer" in sys.modules: + # see the discussion in cmdclass.py:get_cmdclass() + del sys.modules["versioneer"] + + root = get_root() + cfg = get_config_from_root(root) + + assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" + handlers = HANDLERS.get(cfg.VCS) + assert handlers, "unrecognized VCS '%s'" % cfg.VCS + verbose = verbose or cfg.verbose + assert cfg.versionfile_source is not None, \ + "please set versioneer.versionfile_source" + assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" + + versionfile_abs = os.path.join(root, cfg.versionfile_source) + + # extract version from first of: _version.py, VCS command (e.g. 'git + # describe'), parentdir. This is meant to work for developers using a + # source checkout, for users of a tarball created by 'setup.py sdist', + # and for users of a tarball/zipball created by 'git archive' or github's + # download-from-tag feature or the equivalent in other VCSes. + + get_keywords_f = handlers.get("get_keywords") + from_keywords_f = handlers.get("keywords") + if get_keywords_f and from_keywords_f: + try: + keywords = get_keywords_f(versionfile_abs) + ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) + if verbose: + print("got version from expanded keyword %s" % ver) + return ver + except NotThisMethod: + pass + + try: + ver = versions_from_file(versionfile_abs) + if verbose: + print("got version from file %s %s" % (versionfile_abs, ver)) + return ver + except NotThisMethod: + pass + + from_vcs_f = handlers.get("pieces_from_vcs") + if from_vcs_f: + try: + pieces = from_vcs_f(cfg.tag_prefix, root, verbose) + ver = render(pieces, cfg.style) + if verbose: + print("got version from VCS %s" % ver) + return ver + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + if verbose: + print("got version from parentdir %s" % ver) + return ver + except NotThisMethod: + pass + + if verbose: + print("unable to compute version") + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, "error": "unable to compute version", + "date": None} + + +def get_version(): + """Get the short version string for this project.""" + return get_versions()["version"] + + +def get_cmdclass(): + """Get the custom setuptools/distutils subclasses used by Versioneer.""" + if "versioneer" in sys.modules: + del sys.modules["versioneer"] + # this fixes the "python setup.py develop" case (also 'install' and + # 'easy_install .'), in which subdependencies of the main project are + # built (using setup.py bdist_egg) in the same python process. Assume + # a main project A and a dependency B, which use different versions + # of Versioneer. A's setup.py imports A's Versioneer, leaving it in + # sys.modules by the time B's setup.py is executed, causing B to run + # with the wrong versioneer. Setuptools wraps the sub-dep builds in a + # sandbox that restores sys.modules to it's pre-build state, so the + # parent is protected against the child's "import versioneer". By + # removing ourselves from sys.modules here, before the child build + # happens, we protect the child from the parent's versioneer too. + # Also see https://github.com/warner/python-versioneer/issues/52 + + cmds = {} + + # we add "version" to both distutils and setuptools + from distutils.core import Command + + class cmd_version(Command): + description = "report generated version string" + user_options = [] + boolean_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + vers = get_versions(verbose=True) + print("Version: %s" % vers["version"]) + print(" full-revisionid: %s" % vers.get("full-revisionid")) + print(" dirty: %s" % vers.get("dirty")) + print(" date: %s" % vers.get("date")) + if vers["error"]: + print(" error: %s" % vers["error"]) + cmds["version"] = cmd_version + + # we override "build_py" in both distutils and setuptools + # + # most invocation pathways end up running build_py: + # distutils/build -> build_py + # distutils/install -> distutils/build ->.. + # setuptools/bdist_wheel -> distutils/install ->.. + # setuptools/bdist_egg -> distutils/install_lib -> build_py + # setuptools/install -> bdist_egg ->.. + # setuptools/develop -> ? + # pip install: + # copies source tree to a tempdir before running egg_info/etc + # if .git isn't copied too, 'git describe' will fail + # then does setup.py bdist_wheel, or sometimes setup.py install + # setup.py egg_info -> ? + + # we override different "build_py" commands for both environments + if "setuptools" in sys.modules: + from setuptools.command.build_py import build_py as _build_py + else: + from distutils.command.build_py import build_py as _build_py + + class cmd_build_py(_build_py): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_py.run(self) + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if cfg.versionfile_build: + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + cmds["build_py"] = cmd_build_py + + if "cx_Freeze" in sys.modules: # cx_freeze enabled? + from cx_Freeze.dist import build_exe as _build_exe + # nczeczulin reports that py2exe won't like the pep440-style string + # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. + # setup(console=[{ + # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION + # "product_version": versioneer.get_version(), + # ... + + class cmd_build_exe(_build_exe): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _build_exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["build_exe"] = cmd_build_exe + del cmds["build_py"] + + if 'py2exe' in sys.modules: # py2exe enabled? + try: + from py2exe.distutils_buildexe import py2exe as _py2exe # py3 + except ImportError: + from py2exe.build_exe import py2exe as _py2exe # py2 + + class cmd_py2exe(_py2exe): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _py2exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + cmds["py2exe"] = cmd_py2exe + + # we override different "sdist" commands for both environments + if "setuptools" in sys.modules: + from setuptools.command.sdist import sdist as _sdist + else: + from distutils.command.sdist import sdist as _sdist + + class cmd_sdist(_sdist): + def run(self): + versions = get_versions() + self._versioneer_generated_versions = versions + # unless we update this, the command will keep using the old + # version + self.distribution.metadata.version = versions["version"] + return _sdist.run(self) + + def make_release_tree(self, base_dir, files): + root = get_root() + cfg = get_config_from_root(root) + _sdist.make_release_tree(self, base_dir, files) + # now locate _version.py in the new base_dir directory + # (remembering that it may be a hardlink) and replace it with an + # updated value + target_versionfile = os.path.join(base_dir, cfg.versionfile_source) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, + self._versioneer_generated_versions) + cmds["sdist"] = cmd_sdist + + return cmds + + +CONFIG_ERROR = """ +setup.cfg is missing the necessary Versioneer configuration. You need +a section like: + + [versioneer] + VCS = git + style = pep440 + versionfile_source = src/myproject/_version.py + versionfile_build = myproject/_version.py + tag_prefix = + parentdir_prefix = myproject- + +You will also need to edit your setup.py to use the results: + + import versioneer + setup(version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), ...) + +Please read the docstring in ./versioneer.py for configuration instructions, +edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. +""" + +SAMPLE_CONFIG = """ +# See the docstring in versioneer.py for instructions. Note that you must +# re-run 'versioneer.py setup' after changing this section, and commit the +# resulting files. + +[versioneer] +#VCS = git +#style = pep440 +#versionfile_source = +#versionfile_build = +#tag_prefix = +#parentdir_prefix = + +""" + +INIT_PY_SNIPPET = """ +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions +""" + + +def do_setup(): + """Main VCS-independent setup function for installing Versioneer.""" + root = get_root() + try: + cfg = get_config_from_root(root) + except (EnvironmentError, configparser.NoSectionError, + configparser.NoOptionError) as e: + if isinstance(e, (EnvironmentError, configparser.NoSectionError)): + print("Adding sample versioneer config to setup.cfg", + file=sys.stderr) + with open(os.path.join(root, "setup.cfg"), "a") as f: + f.write(SAMPLE_CONFIG) + print(CONFIG_ERROR, file=sys.stderr) + return 1 + + print(" creating %s" % cfg.versionfile_source) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write(LONG % {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), + "__init__.py") + if os.path.exists(ipy): + try: + with open(ipy, "r") as f: + old = f.read() + except EnvironmentError: + old = "" + if INIT_PY_SNIPPET not in old: + print(" appending to %s" % ipy) + with open(ipy, "a") as f: + f.write(INIT_PY_SNIPPET) + else: + print(" %s unmodified" % ipy) + else: + print(" %s doesn't exist, ok" % ipy) + ipy = None + + # Make sure both the top-level "versioneer.py" and versionfile_source + # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so + # they'll be copied into source distributions. Pip won't be able to + # install the package without this. + manifest_in = os.path.join(root, "MANIFEST.in") + simple_includes = set() + try: + with open(manifest_in, "r") as f: + for line in f: + if line.startswith("include "): + for include in line.split()[1:]: + simple_includes.add(include) + except EnvironmentError: + pass + # That doesn't cover everything MANIFEST.in can do + # (http://docs.python.org/2/distutils/sourcedist.html#commands), so + # it might give some false negatives. Appending redundant 'include' + # lines is safe, though. + if "versioneer.py" not in simple_includes: + print(" appending 'versioneer.py' to MANIFEST.in") + with open(manifest_in, "a") as f: + f.write("include versioneer.py\n") + else: + print(" 'versioneer.py' already in MANIFEST.in") + if cfg.versionfile_source not in simple_includes: + print(" appending versionfile_source ('%s') to MANIFEST.in" % + cfg.versionfile_source) + with open(manifest_in, "a") as f: + f.write("include %s\n" % cfg.versionfile_source) + else: + print(" versionfile_source already in MANIFEST.in") + + # Make VCS-specific changes. For git, this means creating/changing + # .gitattributes to mark _version.py for export-subst keyword + # substitution. + do_vcs_install(manifest_in, cfg.versionfile_source, ipy) + return 0 + + +def scan_setup_py(): + """Validate the contents of setup.py against Versioneer's expectations.""" + found = set() + setters = False + errors = 0 + with open("setup.py", "r") as f: + for line in f.readlines(): + if "import versioneer" in line: + found.add("import") + if "versioneer.get_cmdclass()" in line: + found.add("cmdclass") + if "versioneer.get_version()" in line: + found.add("get_version") + if "versioneer.VCS" in line: + setters = True + if "versioneer.versionfile_source" in line: + setters = True + if len(found) != 3: + print("") + print("Your setup.py appears to be missing some important items") + print("(but I might be wrong). Please make sure it has something") + print("roughly like the following:") + print("") + print(" import versioneer") + print(" setup( version=versioneer.get_version(),") + print(" cmdclass=versioneer.get_cmdclass(), ...)") + print("") + errors += 1 + if setters: + print("You should remove lines like 'versioneer.VCS = ' and") + print("'versioneer.versionfile_source = ' . This configuration") + print("now lives in setup.cfg, and should be removed from setup.py") + print("") + errors += 1 + return errors + + +if __name__ == "__main__": + cmd = sys.argv[1] + if cmd == "setup": + errors = do_setup() + errors += scan_setup_py() + if errors: + sys.exit(1)