diff --git a/beat/backend/python/database.py b/beat/backend/python/database.py
index c8104406230411a384172d69e646cb65f68dbc65..c6d2fa76b43fd1aa8b730f2d6e362126a70ff047 100644
--- a/beat/backend/python/database.py
+++ b/beat/backend/python/database.py
@@ -392,6 +392,12 @@ class Database(object):
 
         return not bool(self.errors)
 
+    @property
+    def environment(self):
+        """Returns the run environment if any has been set"""
+
+        return self.data.get("environment")
+
     @property
     def protocols(self):
         """The declaration of all the protocols of the database"""
diff --git a/beat/backend/python/test/prefix/databases/integers_db_env/1.json b/beat/backend/python/test/prefix/databases/integers_db_env/1.json
new file mode 100644
index 0000000000000000000000000000000000000000..71a4ad1b84ce7a9bbb6186a07d7cb6e3755959f7
--- /dev/null
+++ b/beat/backend/python/test/prefix/databases/integers_db_env/1.json
@@ -0,0 +1,99 @@
+{
+    "root_folder": "/tmp/path/not/set",
+    "environment": {
+        "name": "Example databases",
+        "version": "1.4.0"
+    },
+    "protocols": [
+        {
+            "name": "double",
+            "template": "double",
+            "sets": [
+                {
+                    "name": "double",
+                    "template": "double",
+                    "view": "Double",
+                    "outputs": {
+                        "a": "user/single_integer/1",
+                        "b": "user/single_integer/1",
+                        "sum": "user/single_integer/1"
+                    }
+                }
+            ]
+        },
+        {
+            "name": "triple",
+            "template": "triple",
+            "sets": [
+                {
+                    "name": "triple",
+                    "view": "Triple",
+                    "template": "triple",
+                    "outputs": {
+                        "a": "user/single_integer/1",
+                        "b": "user/single_integer/1",
+                        "c": "user/single_integer/1",
+                        "sum": "user/single_integer/1"
+                    }
+                }
+            ]
+        },
+        {
+            "name": "two_sets",
+            "template": "two_sets",
+            "sets": [
+                {
+                    "name": "double",
+                    "template": "double",
+                    "view": "Double",
+                    "outputs": {
+                        "a": "user/single_integer/1",
+                        "b": "user/single_integer/1",
+                        "sum": "user/single_integer/1"
+                    }
+                },
+                {
+                    "name": "triple",
+                    "template": "triple",
+                    "view": "Triple",
+                    "outputs": {
+                        "a": "user/single_integer/1",
+                        "b": "user/single_integer/1",
+                        "c": "user/single_integer/1",
+                        "sum": "user/single_integer/1"
+                    }
+                }
+            ]
+        },
+        {
+            "name": "labelled",
+            "template": "labelled",
+            "sets": [
+                {
+                    "name": "labelled",
+                    "template": "labelled",
+                    "view": "Labelled",
+                    "outputs": {
+                        "value": "user/single_integer/1",
+                        "label": "user/single_string/1"
+                    }
+                }
+            ]
+        },
+        {
+            "name": "different_frequencies",
+            "template": "different_frequencies",
+            "sets": [
+                {
+                    "name": "double",
+                    "template": "double",
+                    "view": "DifferentFrequencies",
+                    "outputs": {
+                        "a": "user/single_integer/1",
+                        "b": "user/single_integer/1"
+                    }
+                }
+            ]
+        }
+    ]
+}
diff --git a/beat/backend/python/test/prefix/databases/integers_db_env/1.py b/beat/backend/python/test/prefix/databases/integers_db_env/1.py
new file mode 100755
index 0000000000000000000000000000000000000000..0ebebd6c4debec559f8a853830073e92a8b71bd5
--- /dev/null
+++ b/beat/backend/python/test/prefix/databases/integers_db_env/1.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+
+###################################################################################
+#                                                                                 #
+# Copyright (c) 2019 Idiap Research Institute, http://www.idiap.ch/               #
+# Contact: beat.support@idiap.ch                                                  #
+#                                                                                 #
+# Redistribution and use in source and binary forms, with or without              #
+# modification, are permitted provided that the following conditions are met:     #
+#                                                                                 #
+# 1. Redistributions of source code must retain the above copyright notice, this  #
+# list of conditions and the following disclaimer.                                #
+#                                                                                 #
+# 2. Redistributions in binary form must reproduce the above copyright notice,    #
+# this list of conditions and the following disclaimer in the documentation       #
+# and/or other materials provided with the distribution.                          #
+#                                                                                 #
+# 3. Neither the name of the copyright holder nor the names of its contributors   #
+# may be used to endorse or promote products derived from this software without   #
+# specific prior written permission.                                              #
+#                                                                                 #
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED   #
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE          #
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE    #
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL      #
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      #
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER      #
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,   #
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   #
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.            #
+#                                                                                 #
+###################################################################################
+
+
+import numpy
+from collections import namedtuple
+from beat.backend.python.database import View
+
+
+class Double(View):
+    def index(self, root_folder, parameters):
+        Entry = namedtuple("Entry", ["a", "b", "sum"])
+
+        return [
+            Entry(1, 10, 11),
+            Entry(2, 20, 22),
+            Entry(3, 30, 33),
+            Entry(4, 40, 44),
+            Entry(5, 50, 55),
+            Entry(6, 60, 66),
+            Entry(7, 70, 77),
+            Entry(8, 80, 88),
+            Entry(9, 90, 99),
+        ]
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == "a":
+            return {"value": numpy.int32(obj.a)}
+
+        elif output == "b":
+            return {"value": numpy.int32(obj.b)}
+
+        elif output == "sum":
+            return {"value": numpy.int32(obj.sum)}
+        elif output == "class":
+            return {"value": numpy.int32(obj.cls)}
+
+
+# ----------------------------------------------------------
+
+
+class Triple(View):
+    def index(self, root_folder, parameters):
+        Entry = namedtuple("Entry", ["a", "b", "c", "sum"])
+
+        return [
+            Entry(1, 10, 100, 111),
+            Entry(2, 20, 200, 222),
+            Entry(3, 30, 300, 333),
+            Entry(4, 40, 400, 444),
+            Entry(5, 50, 500, 555),
+            Entry(6, 60, 600, 666),
+            Entry(7, 70, 700, 777),
+            Entry(8, 80, 800, 888),
+            Entry(9, 90, 900, 999),
+        ]
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == "a":
+            return {"value": numpy.int32(obj.a)}
+
+        elif output == "b":
+            return {"value": numpy.int32(obj.b)}
+
+        elif output == "c":
+            return {"value": numpy.int32(obj.c)}
+
+        elif output == "sum":
+            return {"value": numpy.int32(obj.sum)}
+
+
+# ----------------------------------------------------------
+
+
+class Labelled(View):
+    def index(self, root_folder, parameters):
+        Entry = namedtuple("Entry", ["label", "value"])
+
+        return [
+            Entry("A", 1),
+            Entry("A", 2),
+            Entry("A", 3),
+            Entry("A", 4),
+            Entry("A", 5),
+            Entry("B", 10),
+            Entry("B", 20),
+            Entry("B", 30),
+            Entry("B", 40),
+            Entry("B", 50),
+            Entry("C", 100),
+            Entry("C", 200),
+            Entry("C", 300),
+            Entry("C", 400),
+            Entry("C", 500),
+        ]
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == "label":
+            return {"value": obj.label}
+
+        elif output == "value":
+            return {"value": numpy.int32(obj.value)}
+
+
+# ----------------------------------------------------------
+
+
+class DifferentFrequencies(View):
+    def index(self, root_folder, parameters):
+        Entry = namedtuple("Entry", ["a", "b"])
+
+        return [
+            Entry(1, 10),
+            Entry(1, 20),
+            Entry(1, 30),
+            Entry(1, 40),
+            Entry(2, 50),
+            Entry(2, 60),
+            Entry(2, 70),
+            Entry(2, 80),
+        ]
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == "a":
+            return {"value": numpy.int32(obj.a)}
+
+        elif output == "b":
+            return {"value": numpy.int32(obj.b)}
diff --git a/beat/backend/python/test/prefix/databases/integers_db_env/2.json b/beat/backend/python/test/prefix/databases/integers_db_env/2.json
new file mode 100644
index 0000000000000000000000000000000000000000..636da24bf0f79fcdb0c7a4fe333356152fa6809f
--- /dev/null
+++ b/beat/backend/python/test/prefix/databases/integers_db_env/2.json
@@ -0,0 +1,58 @@
+{
+    "schema_version": 2,
+    "environment": {
+        "name": "Example databases",
+        "version": "1.4.0"
+    },
+    "root_folder": "/tmp/path/not/set",
+    "protocols": [
+        {
+            "name": "double",
+            "template": "double/1",
+            "views": {
+                "double": {
+                   "view": "Double"
+                }
+            }
+        },
+        {
+            "name": "triple",
+            "template": "triple/1",
+            "views": {
+                "triple": {
+                   "view": "Triple"
+                }
+            }
+        },
+        {
+            "name": "two_sets",
+            "template": "two_sets/1",
+            "views": {
+                "double": {
+                   "view": "Double"
+                },
+                "triple": {
+                   "view": "Triple"
+                }
+            }
+        },
+        {
+            "name": "labelled",
+            "template": "labelled/1",
+            "views": {
+                "labelled": {
+                   "view": "Labelled"
+                }
+            }
+        },
+        {
+            "name": "different_frequencies",
+            "template": "different_frequencies/1",
+            "views": {
+                "double" : {
+                   "view": "DifferentFrequencies"
+                }
+            }
+        }
+    ]
+}
diff --git a/beat/backend/python/test/prefix/databases/integers_db_env/2.py b/beat/backend/python/test/prefix/databases/integers_db_env/2.py
new file mode 100644
index 0000000000000000000000000000000000000000..0ebebd6c4debec559f8a853830073e92a8b71bd5
--- /dev/null
+++ b/beat/backend/python/test/prefix/databases/integers_db_env/2.py
@@ -0,0 +1,168 @@
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+
+###################################################################################
+#                                                                                 #
+# Copyright (c) 2019 Idiap Research Institute, http://www.idiap.ch/               #
+# Contact: beat.support@idiap.ch                                                  #
+#                                                                                 #
+# Redistribution and use in source and binary forms, with or without              #
+# modification, are permitted provided that the following conditions are met:     #
+#                                                                                 #
+# 1. Redistributions of source code must retain the above copyright notice, this  #
+# list of conditions and the following disclaimer.                                #
+#                                                                                 #
+# 2. Redistributions in binary form must reproduce the above copyright notice,    #
+# this list of conditions and the following disclaimer in the documentation       #
+# and/or other materials provided with the distribution.                          #
+#                                                                                 #
+# 3. Neither the name of the copyright holder nor the names of its contributors   #
+# may be used to endorse or promote products derived from this software without   #
+# specific prior written permission.                                              #
+#                                                                                 #
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED   #
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE          #
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE    #
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL      #
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      #
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER      #
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,   #
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   #
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.            #
+#                                                                                 #
+###################################################################################
+
+
+import numpy
+from collections import namedtuple
+from beat.backend.python.database import View
+
+
+class Double(View):
+    def index(self, root_folder, parameters):
+        Entry = namedtuple("Entry", ["a", "b", "sum"])
+
+        return [
+            Entry(1, 10, 11),
+            Entry(2, 20, 22),
+            Entry(3, 30, 33),
+            Entry(4, 40, 44),
+            Entry(5, 50, 55),
+            Entry(6, 60, 66),
+            Entry(7, 70, 77),
+            Entry(8, 80, 88),
+            Entry(9, 90, 99),
+        ]
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == "a":
+            return {"value": numpy.int32(obj.a)}
+
+        elif output == "b":
+            return {"value": numpy.int32(obj.b)}
+
+        elif output == "sum":
+            return {"value": numpy.int32(obj.sum)}
+        elif output == "class":
+            return {"value": numpy.int32(obj.cls)}
+
+
+# ----------------------------------------------------------
+
+
+class Triple(View):
+    def index(self, root_folder, parameters):
+        Entry = namedtuple("Entry", ["a", "b", "c", "sum"])
+
+        return [
+            Entry(1, 10, 100, 111),
+            Entry(2, 20, 200, 222),
+            Entry(3, 30, 300, 333),
+            Entry(4, 40, 400, 444),
+            Entry(5, 50, 500, 555),
+            Entry(6, 60, 600, 666),
+            Entry(7, 70, 700, 777),
+            Entry(8, 80, 800, 888),
+            Entry(9, 90, 900, 999),
+        ]
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == "a":
+            return {"value": numpy.int32(obj.a)}
+
+        elif output == "b":
+            return {"value": numpy.int32(obj.b)}
+
+        elif output == "c":
+            return {"value": numpy.int32(obj.c)}
+
+        elif output == "sum":
+            return {"value": numpy.int32(obj.sum)}
+
+
+# ----------------------------------------------------------
+
+
+class Labelled(View):
+    def index(self, root_folder, parameters):
+        Entry = namedtuple("Entry", ["label", "value"])
+
+        return [
+            Entry("A", 1),
+            Entry("A", 2),
+            Entry("A", 3),
+            Entry("A", 4),
+            Entry("A", 5),
+            Entry("B", 10),
+            Entry("B", 20),
+            Entry("B", 30),
+            Entry("B", 40),
+            Entry("B", 50),
+            Entry("C", 100),
+            Entry("C", 200),
+            Entry("C", 300),
+            Entry("C", 400),
+            Entry("C", 500),
+        ]
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == "label":
+            return {"value": obj.label}
+
+        elif output == "value":
+            return {"value": numpy.int32(obj.value)}
+
+
+# ----------------------------------------------------------
+
+
+class DifferentFrequencies(View):
+    def index(self, root_folder, parameters):
+        Entry = namedtuple("Entry", ["a", "b"])
+
+        return [
+            Entry(1, 10),
+            Entry(1, 20),
+            Entry(1, 30),
+            Entry(1, 40),
+            Entry(2, 50),
+            Entry(2, 60),
+            Entry(2, 70),
+            Entry(2, 80),
+        ]
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == "a":
+            return {"value": numpy.int32(obj.a)}
+
+        elif output == "b":
+            return {"value": numpy.int32(obj.b)}
diff --git a/beat/backend/python/test/test_database.py b/beat/backend/python/test/test_database.py
index 3b68145b78de1da15c63eff41cd444a87032ea2d..7720fce7a68b4c60d91cb5e13c1d5c72a8744df2 100644
--- a/beat/backend/python/test/test_database.py
+++ b/beat/backend/python/test/test_database.py
@@ -161,3 +161,23 @@ def test_duplicate_key_error():
     database = Database(prefix, "duplicate_key_error/1")
     nose.tools.assert_false(database.valid)
     nose.tools.assert_true("Database declaration file invalid" in database.errors[0])
+
+
+# ----------------------------------------------------------
+
+REFERENCE_ENVIRONMENT = {"name": "Example databases", "version": "1.4.0"}
+
+
+def test_envionment_requirement():
+    for db_name in INTEGERS_DBS:
+        yield compare_environment, db_name, None
+
+    for index in range(1, 3):
+        yield compare_environment, "integers_db_env/{}".format(
+            index
+        ), REFERENCE_ENVIRONMENT
+
+
+def compare_environment(db_name, environment):
+    db = load(db_name)
+    nose.tools.assert_equal(db.environment, environment)