diff --git a/.jupyter/api_authentication/__init__.py b/.jupyter/api_authentication/__init__.py
index 2c48db22770b0ebd34d7872a2dc7cd1416837ec2..1caebb3b03385e64cd4896ea7b633296e3edd37a 100644
--- a/.jupyter/api_authentication/__init__.py
+++ b/.jupyter/api_authentication/__init__.py
@@ -43,4 +43,5 @@ from api_authentication.models.user_forgot_dto import UserForgotDto
 from api_authentication.models.user_password_dto import UserPasswordDto
 from api_authentication.models.user_reset_dto import UserResetDto
 from api_authentication.models.user_roles_dto import UserRolesDto
+from api_authentication.models.user_theme_set_dto import UserThemeSetDto
 from api_authentication.models.user_update_dto import UserUpdateDto
diff --git a/.jupyter/api_authentication/api/user_endpoint_api.py b/.jupyter/api_authentication/api/user_endpoint_api.py
index 91343f15a8384bb3dffbbb29f01fb7fa93e51591..40ba9632a02912ec9fd5d6167d27b8b14ebe7760 100644
--- a/.jupyter/api_authentication/api/user_endpoint_api.py
+++ b/.jupyter/api_authentication/api/user_endpoint_api.py
@@ -920,3 +920,108 @@ class UserEndpointApi(object):
             _preload_content=params.get('_preload_content', True),
             _request_timeout=params.get('_request_timeout'),
             collection_formats=collection_formats)
+
+    def update_theme(self, body, id, **kwargs):  # noqa: E501
+        """Update user theme  # noqa: E501
+
+        This method makes a synchronous HTTP request by default. To make an
+        asynchronous HTTP request, please pass async_req=True
+        >>> thread = api.update_theme(body, id, async_req=True)
+        >>> result = thread.get()
+
+        :param async_req bool
+        :param UserThemeSetDto body: (required)
+        :param int id: (required)
+        :return: None
+                 If the method is called asynchronously,
+                 returns the request thread.
+        """
+        kwargs['_return_http_data_only'] = True
+        if kwargs.get('async_req'):
+            return self.update_theme_with_http_info(body, id, **kwargs)  # noqa: E501
+        else:
+            (data) = self.update_theme_with_http_info(body, id, **kwargs)  # noqa: E501
+            return data
+
+    def update_theme_with_http_info(self, body, id, **kwargs):  # noqa: E501
+        """Update user theme  # noqa: E501
+
+        This method makes a synchronous HTTP request by default. To make an
+        asynchronous HTTP request, please pass async_req=True
+        >>> thread = api.update_theme_with_http_info(body, id, async_req=True)
+        >>> result = thread.get()
+
+        :param async_req bool
+        :param UserThemeSetDto body: (required)
+        :param int id: (required)
+        :return: None
+                 If the method is called asynchronously,
+                 returns the request thread.
+        """
+
+        all_params = ['body', 'id']  # noqa: E501
+        all_params.append('async_req')
+        all_params.append('_return_http_data_only')
+        all_params.append('_preload_content')
+        all_params.append('_request_timeout')
+
+        params = locals()
+        for key, val in six.iteritems(params['kwargs']):
+            if key not in all_params:
+                raise TypeError(
+                    "Got an unexpected keyword argument '%s'"
+                    " to method update_theme" % key
+                )
+            params[key] = val
+        del params['kwargs']
+        # verify the required parameter 'body' is set
+        if ('body' not in params or
+                params['body'] is None):
+            raise ValueError("Missing the required parameter `body` when calling `update_theme`")  # noqa: E501
+        # verify the required parameter 'id' is set
+        if ('id' not in params or
+                params['id'] is None):
+            raise ValueError("Missing the required parameter `id` when calling `update_theme`")  # noqa: E501
+
+        collection_formats = {}
+
+        path_params = {}
+        if 'id' in params:
+            path_params['id'] = params['id']  # noqa: E501
+
+        query_params = []
+
+        header_params = {}
+
+        form_params = []
+        local_var_files = {}
+
+        body_params = None
+        if 'body' in params:
+            body_params = params['body']
+        # HTTP header `Accept`
+        header_params['Accept'] = self.api_client.select_header_accept(
+            ['*/*'])  # noqa: E501
+
+        # HTTP header `Content-Type`
+        header_params['Content-Type'] = self.api_client.select_header_content_type(  # noqa: E501
+            ['application/json'])  # noqa: E501
+
+        # Authentication setting
+        auth_settings = ['bearerAuth']  # noqa: E501
+
+        return self.api_client.call_api(
+            '/api/user/{id}/theme', 'PUT',
+            path_params,
+            query_params,
+            header_params,
+            body=body_params,
+            post_params=form_params,
+            files=local_var_files,
+            response_type=None,  # noqa: E501
+            auth_settings=auth_settings,
+            async_req=params.get('async_req'),
+            _return_http_data_only=params.get('_return_http_data_only'),
+            _preload_content=params.get('_preload_content', True),
+            _request_timeout=params.get('_request_timeout'),
+            collection_formats=collection_formats)
diff --git a/.jupyter/api_authentication/models/__init__.py b/.jupyter/api_authentication/models/__init__.py
index 11e22a17bacc695efc8b6692fac98724d7c4c9a2..0cd55935b61999c415fd3e89ff72c48c4effe5f6 100644
--- a/.jupyter/api_authentication/models/__init__.py
+++ b/.jupyter/api_authentication/models/__init__.py
@@ -35,4 +35,5 @@ from api_authentication.models.user_forgot_dto import UserForgotDto
 from api_authentication.models.user_password_dto import UserPasswordDto
 from api_authentication.models.user_reset_dto import UserResetDto
 from api_authentication.models.user_roles_dto import UserRolesDto
+from api_authentication.models.user_theme_set_dto import UserThemeSetDto
 from api_authentication.models.user_update_dto import UserUpdateDto
diff --git a/.jupyter/api_query/api/table_data_endpoint_api.py b/.jupyter/api_query/api/table_data_endpoint_api.py
index 5cfffc839b17b76394c5abd0592da4b8df92e7fd..31b90e9df370ce626ce7767d44cdef26d2f1b7d7 100644
--- a/.jupyter/api_query/api/table_data_endpoint_api.py
+++ b/.jupyter/api_query/api/table_data_endpoint_api.py
@@ -259,7 +259,7 @@ class TableDataEndpointApi(object):
         auth_settings = ['bearerAuth']  # noqa: E501
 
         return self.api_client.call_api(
-            '/api/container/{id}/database/{databaseId}/table/{tableId}/data', 'GET',
+            '/api/container/{id}/database/{databaseId}/table/{tableId}/data', 'HEAD',
             path_params,
             query_params,
             header_params,
@@ -380,7 +380,7 @@ class TableDataEndpointApi(object):
         auth_settings = ['bearerAuth']  # noqa: E501
 
         return self.api_client.call_api(
-            '/api/container/{id}/database/{databaseId}/table/{tableId}/data', 'HEAD',
+            '/api/container/{id}/database/{databaseId}/table/{tableId}/data', 'GET',
             path_params,
             query_params,
             header_params,
diff --git a/.jupyter/api_table/__init__.py b/.jupyter/api_table/__init__.py
index beaceff5a74771307782fed7d105c64f63e06540..37441edea5b7655b2a5337e45897d5860cd36e48 100644
--- a/.jupyter/api_table/__init__.py
+++ b/.jupyter/api_table/__init__.py
@@ -24,7 +24,6 @@ from api_table.models.api_error_dto import ApiErrorDto
 from api_table.models.column_create_dto import ColumnCreateDto
 from api_table.models.column_dto import ColumnDto
 from api_table.models.concept_dto import ConceptDto
-from api_table.models.granted_authority_dto import GrantedAuthorityDto
 from api_table.models.image_date_dto import ImageDateDto
 from api_table.models.table_brief_dto import TableBriefDto
 from api_table.models.table_create_dto import TableCreateDto
diff --git a/.jupyter/api_table/models/__init__.py b/.jupyter/api_table/models/__init__.py
index c7a86dfadf16101370f746da857eca3f44cac6a1..65818bef09589a604af11a71cac062d8ca9b09de 100644
--- a/.jupyter/api_table/models/__init__.py
+++ b/.jupyter/api_table/models/__init__.py
@@ -18,7 +18,6 @@ from api_table.models.api_error_dto import ApiErrorDto
 from api_table.models.column_create_dto import ColumnCreateDto
 from api_table.models.column_dto import ColumnDto
 from api_table.models.concept_dto import ConceptDto
-from api_table.models.granted_authority_dto import GrantedAuthorityDto
 from api_table.models.image_date_dto import ImageDateDto
 from api_table.models.table_brief_dto import TableBriefDto
 from api_table.models.table_create_dto import TableCreateDto
diff --git a/.jupyter/load_test.py b/.jupyter/load_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..4f395a950b82a9bde1010cb4c6a4a4c7672aa248
--- /dev/null
+++ b/.jupyter/load_test.py
@@ -0,0 +1,273 @@
+#!/bin/env python3
+
+import time
+import os
+import shutil
+import uuid
+import sys
+
+import api_query.rest
+from api_authentication.api.authentication_endpoint_api import AuthenticationEndpointApi
+from api_authentication.api.user_endpoint_api import UserEndpointApi
+from api_container.api.container_endpoint_api import ContainerEndpointApi
+from api_database.api.container_database_endpoint_api import ContainerDatabaseEndpointApi
+from api_table.api.table_endpoint_api import TableEndpointApi
+from api_query.api.table_data_endpoint_api import TableDataEndpointApi
+from api_query.api.query_endpoint_api import QueryEndpointApi
+from api_identifier.api.identifier_endpoint_api import IdentifierEndpointApi
+from api_identifier.api.persistence_endpoint_api import PersistenceEndpointApi
+
+authentication = AuthenticationEndpointApi()
+user = UserEndpointApi()
+container = ContainerEndpointApi()
+database = ContainerDatabaseEndpointApi()
+table = TableEndpointApi()
+query = QueryEndpointApi()
+data = TableDataEndpointApi()
+identifier = IdentifierEndpointApi()
+persistence = PersistenceEndpointApi()
+
+token = ""
+
+
+def create_user(username):
+    response = user.register({
+        "username": username,
+        "password": username,
+        "email": username + "@gmail.com"
+    })
+    print("created user")
+    return response
+
+
+def auth_user(username):
+    response = authentication.authenticate_user1({
+        "username": username,
+        "password": username
+    })
+    print("authenticated user")
+    token = response.token
+    container.api_client.default_headers = {"Authorization": "Bearer " + token}
+    database.api_client.default_headers = {"Authorization": "Bearer " + token}
+    table.api_client.default_headers = {"Authorization": "Bearer " + token}
+    data.api_client.default_headers = {"Authorization": "Bearer " + token}
+    query.api_client.default_headers = {"Authorization": "Bearer " + token}
+    identifier.api_client.default_headers = {"Authorization": "Bearer " + token}
+    user.api_client.default_headers = {"Authorization": "Bearer " + token}
+    persistence.api_client.default_headers = {"Authorization": "Bearer " + token}
+    return response
+
+
+def create_container():
+    response = container.create1({
+        "name": "Airquality " + str(uuid.uuid1()),
+        "repository": "mariadb",
+        "tag": "10.5"
+    })
+    print("created container")
+    return response
+
+
+def start_container(container_id):
+    response = container.modify({
+        "action": "start"
+    }, container_id)
+    time.sleep(5)
+    print("started container")
+    return response
+
+
+def create_database(container_id, is_public=True):
+    response = database.create({
+        "name": "Airquality " + str(uuid.uuid1()),
+        "description": "Hourly measurements in Zürich, Switzerland",
+        "is_public": is_public
+    }, container_id)
+    print("created database")
+    return response
+
+
+def update_database(container_id, database_id, is_public=True):
+    response = database.update({
+        "description": "This dataset includes daily values from 1983 to the current day, divided into annual files. This includes the maximum hourly average and the number of times the hourly average limit value for ozone was exceeded and the daily averages for sulfur dioxide (SO2), carbon monoxide (CO), nitrogen oxide (NOx), nitrogen monoxide (NO), nitrogen dioxide (NO2), particulate matter (PM10 and PM2.5). ) and particle number (PN), provided that they are of sufficient quality. The values of the completed day for the current year are updated every 30 minutes after midnight (UTC+1).",
+        "publisher": "Technical University of Vienna",
+        "license": {
+            "identifier": "CC0-1.0",
+            "uri": "https://creativecommons.org/publicdomain/zero/1.0/legalcode"
+        },
+        "language": "en",
+        "is_public": is_public,
+        "publication": "2022-07-19"
+    }, container_id, database_id)
+    print("updated database")
+    return response
+
+
+def create_table(container_id, database_id, columns=None):
+    if columns is None:
+        columns = [{
+            "name": "Date",
+            "type": "date",
+            "dfid": 1,
+            "unique": False,
+            "primary_key": False,
+            "null_allowed": True,
+        }, {
+            "name": "Location",
+            "type": "string",
+            "unique": False,
+            "primary_key": False,
+            "null_allowed": True,
+        }, {
+            "name": "Parameter",
+            "type": "string",
+            "unique": False,
+            "primary_key": False,
+            "null_allowed": True,
+        }, {
+            "name": "Interval",
+            "type": "string",
+            "unique": False,
+            "primary_key": False,
+            "null_allowed": True,
+        }, {
+            "name": "Unit",
+            "type": "string",
+            "unique": False,
+            "primary_key": False,
+            "null_allowed": True,
+        }, {
+            "name": "Value",
+            "type": "decimal",
+            "unique": False,
+            "primary_key": False,
+            "null_allowed": True,
+        }, {
+            "name": "Status",
+            "type": "string",
+            "unique": False,
+            "primary_key": False,
+            "null_allowed": True,
+        }]
+    response = table.create({
+        "name": "Airquality " + str(uuid.uuid1()),
+        "description": "Airquality in Zürich, Switzerland",
+        "columns": columns
+    }, container_id, database_id)
+    print("created table")
+    return response
+
+
+def find_table(container_id, database_id, table_id):
+    response = table.find_by_id(container_id, database_id, table_id)
+    print("found table")
+    return response
+
+
+def fill_table(container_id, database_id, table_id):
+    shutil.copyfile(os.getcwd() + "/resources/ugz_ogd_air_h1_2021.csv", "/tmp/ugz_ogd_air_h1_2021.csv")
+    response = data.import_csv({
+        "location": "/tmp/ugz_ogd_air_h1_2021.csv",
+        "separator": ",",
+        "quote": "\"",
+        "skip_lines": 1
+    }, container_id, database_id, table_id)
+    print("filled table")
+    return response
+
+
+def create_query(container_id, database_id, statement, page=0, size=3):
+    try:
+        response = query.execute({
+            "statement": statement
+        }, container_id, database_id, page=page, size=size)
+        print("executed query")
+        return response
+    except api_query.rest.ApiException as e:
+        print(e)
+
+
+def create_identifier(container_id, database_id, query_id, visibility="everyone"):
+    response = identifier.create({
+        "qid": query_id,
+        "title": "Airquality",
+        "description": "Subset used for a scientific article",
+        "visibility": visibility,
+        "creators": [{
+            "name": "Weise, Martin",
+            "affiliation": "TU Wien",
+            "orcid": "0000-0003-4216-302X"
+        }, {
+            "name": "Rauber, Andreas",
+            "affiliation": "TU Wien",
+            "orcid": "0000-0002-9272-6225"
+        }],
+        "publication": "2022-07-16",
+        "related_identifiers": [{
+            "value": "http://localhost:3000/container/" + str(container_id) + "/database/" + str(database_id),
+            "type": "URL",
+            "relation": "IsCitedBy"
+        }]
+    }, token, container_id, database_id)
+    print("created identifier")
+    return response
+
+
+if __name__ == '__main__':
+    #
+    # create 1 user and 3 containers (public, private, public)
+    #
+    create_user("test1")
+    auth_user("test1")
+    # container 1
+    cid = create_container().id
+    start_container(cid)
+    dbid = create_database(cid).id
+    update_database(cid, dbid)
+    tid = create_table(cid, dbid).id
+    tname = find_table(cid, dbid, tid).internal_name
+    fill_table(cid, dbid, tid)
+    create_query(cid, dbid, "select `id` from `" + tname + "`")
+    create_query(cid, dbid, "select `date` from `" + tname + "`")
+    qid = create_query(cid, dbid, "select `date`, `location`, `status` from `" + tname + "`").id
+    create_query(cid, dbid, "select `foo` from `" + tname + "`")
+    create_identifier(cid, dbid, qid)
+    # container 2 (=private)
+    cid = create_container().id
+    start_container(cid)
+    dbid = create_database(cid, False).id
+    update_database(cid, dbid, is_public=False)
+    tid = create_table(cid, dbid).id
+    tname = find_table(cid, dbid, tid).internal_name
+    fill_table(cid, dbid, tid)
+    qid = create_query(cid, dbid, "select `id` from `" + tname + "`").id
+    create_identifier(cid, dbid, qid, visibility="self")
+    qid = create_query(cid, dbid, "select `id` from `" + tname + "`").id
+    create_identifier(cid, dbid, qid)
+    # container 3 with 3 tables
+    cid = create_container().id
+    start_container(cid)
+    dbid = create_database(cid).id
+    update_database(cid, dbid)
+    create_table(cid, dbid, columns=[])
+    create_table(cid, dbid, columns=[{
+        "name": "primary",
+        "type": "string",
+        "unique": True,
+        "primary_key": True,
+        "null_allowed": False,
+    }])
+    create_table(cid, dbid, columns=[{
+        "name": "primary",
+        "type": "number",
+        "unique": True,
+        "primary_key": True,
+        "null_allowed": False,
+    }])
+    create_table(cid, dbid, columns=[{
+        "name": "primary",
+        "type": "date",
+        "unique": True,
+        "primary_key": True,
+        "null_allowed": False,
+    }])
diff --git a/.jupyter/test.ipynb b/.jupyter/test.ipynb
deleted file mode 100644
index 7c276b67efa8dde9fe2e055e7b7b669244e8a5f8..0000000000000000000000000000000000000000
--- a/.jupyter/test.ipynb
+++ /dev/null
@@ -1,1013 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   },
-   "source": [
-    "# Test Jupyter Notebook"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 113,
-   "metadata": {
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   },
-   "outputs": [],
-   "source": [
-    "import time\n",
-    "import os\n",
-    "import shutil\n",
-    "import uuid\n",
-    "\n",
-    "from api_authentication.api.authentication_endpoint_api import AuthenticationEndpointApi\n",
-    "from api_authentication.api.user_endpoint_api import UserEndpointApi\n",
-    "from api_container.api.container_endpoint_api import ContainerEndpointApi\n",
-    "from api_database.api.container_database_endpoint_api import ContainerDatabaseEndpointApi\n",
-    "from api_table.api.table_endpoint_api import TableEndpointApi\n",
-    "from api_query.api.table_data_endpoint_api import TableDataEndpointApi\n",
-    "from api_query.api.query_endpoint_api import QueryEndpointApi\n",
-    "from api_identifier.api.identifier_endpoint_api import IdentifierEndpointApi\n",
-    "from api_identifier.api.persistence_endpoint_api import PersistenceEndpointApi\n",
-    "\n",
-    "authentication = AuthenticationEndpointApi()\n",
-    "user = UserEndpointApi()\n",
-    "container = ContainerEndpointApi()\n",
-    "database = ContainerDatabaseEndpointApi()\n",
-    "table = TableEndpointApi()\n",
-    "query = QueryEndpointApi()\n",
-    "data = TableDataEndpointApi()\n",
-    "identifier = IdentifierEndpointApi()\n",
-    "persistence = PersistenceEndpointApi()\n",
-    "\n",
-    "username = \"user\"\n",
-    "password = \"user\"\n",
-    "email = \"someone@example.com\""
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   },
-   "source": [
-    "Create user"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 114,
-   "metadata": {
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'affiliation': None,\n",
-      " 'authorities': [{'authority': 'ROLE_RESEARCHER'}],\n",
-      " 'containers': None,\n",
-      " 'databases': None,\n",
-      " 'email': 'someone@example.com',\n",
-      " 'email_verified': False,\n",
-      " 'firstname': None,\n",
-      " 'id': 2,\n",
-      " 'identifiers': None,\n",
-      " 'lastname': None,\n",
-      " 'orcid': None,\n",
-      " 'theme_dark': False,\n",
-      " 'titles_after': None,\n",
-      " 'titles_before': None,\n",
-      " 'username': 'user'}\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = user.register({\n",
-    "    \"username\": username,\n",
-    "    \"password\": password,\n",
-    "    \"email\": email\n",
-    "})\n",
-    "print(response)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Create token"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 115,
-   "outputs": [],
-   "source": [
-    "response = authentication.authenticate_user1({\n",
-    "    \"username\": username,\n",
-    "    \"password\": password\n",
-    "})\n",
-    "user_id = response.id\n",
-    "token = response.token\n",
-    "container.api_client.default_headers = {\"Authorization\": \"Bearer \" + token}\n",
-    "database.api_client.default_headers = {\"Authorization\": \"Bearer \" + token}\n",
-    "table.api_client.default_headers = {\"Authorization\": \"Bearer \" + token}\n",
-    "data.api_client.default_headers = {\"Authorization\": \"Bearer \" + token}\n",
-    "query.api_client.default_headers = {\"Authorization\": \"Bearer \" + token}\n",
-    "identifier.api_client.default_headers = {\"Authorization\": \"Bearer \" + token}\n",
-    "user.api_client.default_headers = {\"Authorization\": \"Bearer \" + token}\n",
-    "persistence.api_client.default_headers = {\"Authorization\": \"Bearer \" + token}"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Create container"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 116,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'created': datetime.datetime(2022, 7, 26, 13, 5, 36, 339000, tzinfo=tzutc()),\n",
-      " 'creator': {'affiliation': None,\n",
-      "             'authorities': None,\n",
-      "             'email': 'someone@example.com',\n",
-      "             'email_verified': False,\n",
-      "             'firstname': None,\n",
-      "             'id': 2,\n",
-      "             'lastname': None,\n",
-      "             'orcid': None,\n",
-      "             'theme_dark': False,\n",
-      "             'titles_after': None,\n",
-      "             'titles_before': None,\n",
-      "             'username': 'user'},\n",
-      " 'hash': '5dc114629602472d0bb93f4aedd6a38f161dd59ed129247511c83767fcba0a19',\n",
-      " 'id': 1,\n",
-      " 'internal_name': 'fda-userdb-airquality',\n",
-      " 'is_public': None,\n",
-      " 'name': 'Airquality'}\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = container.create1({\n",
-    "    \"name\": \"Airquality\",\n",
-    "    \"repository\": \"mariadb\",\n",
-    "    \"tag\": \"10.5\"\n",
-    "})\n",
-    "container_id = response.id\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Start container"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 117,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'created': datetime.datetime(2022, 7, 26, 13, 5, 36, 339000, tzinfo=tzutc()),\n",
-      " 'creator': {'affiliation': None,\n",
-      "             'authorities': None,\n",
-      "             'email': 'someone@example.com',\n",
-      "             'email_verified': False,\n",
-      "             'firstname': None,\n",
-      "             'id': 2,\n",
-      "             'lastname': None,\n",
-      "             'orcid': None,\n",
-      "             'theme_dark': False,\n",
-      "             'titles_after': None,\n",
-      "             'titles_before': None,\n",
-      "             'username': 'user'},\n",
-      " 'hash': '5dc114629602472d0bb93f4aedd6a38f161dd59ed129247511c83767fcba0a19',\n",
-      " 'id': 1,\n",
-      " 'internal_name': 'fda-userdb-airquality',\n",
-      " 'is_public': None,\n",
-      " 'name': 'Airquality'}\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = container.modify({\n",
-    "    \"action\": \"start\"\n",
-    "}, container_id)\n",
-    "time.sleep(5)\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Create database"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 118,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'container': {'created': datetime.datetime(2022, 7, 26, 13, 5, 36, 339000, tzinfo=tzutc()),\n",
-      "               'creator': {'affiliation': None,\n",
-      "                           'authorities': None,\n",
-      "                           'email': 'someone@example.com',\n",
-      "                           'email_verified': False,\n",
-      "                           'firstname': None,\n",
-      "                           'id': 2,\n",
-      "                           'lastname': None,\n",
-      "                           'orcid': None,\n",
-      "                           'theme_dark': False,\n",
-      "                           'titles_after': None,\n",
-      "                           'titles_before': None,\n",
-      "                           'username': 'user'},\n",
-      "               'hash': '5dc114629602472d0bb93f4aedd6a38f161dd59ed129247511c83767fcba0a19',\n",
-      "               'id': 1,\n",
-      "               'internal_name': 'fda-userdb-airquality',\n",
-      "               'is_public': None,\n",
-      "               'name': 'Airquality'},\n",
-      " 'created': datetime.datetime(2022, 7, 26, 13, 5, 42, 453000, tzinfo=tzutc()),\n",
-      " 'creator': {'affiliation': None,\n",
-      "             'authorities': None,\n",
-      "             'email': 'someone@example.com',\n",
-      "             'email_verified': False,\n",
-      "             'firstname': None,\n",
-      "             'id': 2,\n",
-      "             'lastname': None,\n",
-      "             'orcid': None,\n",
-      "             'theme_dark': False,\n",
-      "             'titles_after': None,\n",
-      "             'titles_before': None,\n",
-      "             'username': 'user'},\n",
-      " 'description': 'Hourly measurements in Zürich, Switzerland',\n",
-      " 'engine': 'mariadb:10.5',\n",
-      " 'id': 1,\n",
-      " 'is_public': True,\n",
-      " 'name': 'Airquality'}\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = database.create({\n",
-    "    \"name\": \"Airquality\",\n",
-    "    \"description\": \"Hourly measurements in Zürich, Switzerland\",\n",
-    "    \"is_public\": True\n",
-    "}, container_id)\n",
-    "database_id = response.id\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Inspect database"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 119,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'contact': None,\n",
-      " 'container': {'created': datetime.datetime(2022, 7, 26, 13, 5, 36, 339000, tzinfo=tzutc()),\n",
-      "               'databases': None,\n",
-      "               'hash': '5dc114629602472d0bb93f4aedd6a38f161dd59ed129247511c83767fcba0a19',\n",
-      "               'id': 1,\n",
-      "               'image': {'id': 1, 'repository': 'mariadb', 'tag': '10.5'},\n",
-      "               'internal_name': 'fda-userdb-airquality',\n",
-      "               'ip_address': None,\n",
-      "               'is_public': None,\n",
-      "               'name': 'Airquality',\n",
-      "               'port': 35358,\n",
-      "               'state': None},\n",
-      " 'created': datetime.datetime(2022, 7, 26, 13, 5, 42, 453000, tzinfo=tzutc()),\n",
-      " 'creator': {'affiliation': None,\n",
-      "             'authorities': None,\n",
-      "             'containers': None,\n",
-      "             'databases': None,\n",
-      "             'email': 'someone@example.com',\n",
-      "             'email_verified': False,\n",
-      "             'firstname': None,\n",
-      "             'id': 2,\n",
-      "             'identifiers': None,\n",
-      "             'lastname': None,\n",
-      "             'orcid': None,\n",
-      "             'theme_dark': False,\n",
-      "             'titles_after': None,\n",
-      "             'titles_before': None,\n",
-      "             'username': 'user'},\n",
-      " 'deleted': None,\n",
-      " 'description': 'Hourly measurements in Zürich, Switzerland',\n",
-      " 'exchange': 'airquality',\n",
-      " 'id': 1,\n",
-      " 'image': {'compiled': None,\n",
-      "           'date_formats': [{'created_at': datetime.datetime(2022, 7, 26, 13, 1, 15, 747000, tzinfo=tzutc()),\n",
-      "                             'database_format': '%Y-%c-%d',\n",
-      "                             'example': '2022-01-30',\n",
-      "                             'has_time': False,\n",
-      "                             'id': 1,\n",
-      "                             'unix_format': 'yyyy-MM-dd'},\n",
-      "                            {'created_at': datetime.datetime(2022, 7, 26, 13, 1, 15, 753000, tzinfo=tzutc()),\n",
-      "                             'database_format': '%d.%c.%Y',\n",
-      "                             'example': '30.01.2022',\n",
-      "                             'has_time': False,\n",
-      "                             'id': 2,\n",
-      "                             'unix_format': 'yyyy-MM-dd'},\n",
-      "                            {'created_at': datetime.datetime(2022, 7, 26, 13, 1, 15, 756000, tzinfo=tzutc()),\n",
-      "                             'database_format': '%d.%c.%y',\n",
-      "                             'example': '30.01.22',\n",
-      "                             'has_time': False,\n",
-      "                             'id': 3,\n",
-      "                             'unix_format': 'yyyy-MM-dd'},\n",
-      "                            {'created_at': datetime.datetime(2022, 7, 26, 13, 1, 15, 759000, tzinfo=tzutc()),\n",
-      "                             'database_format': '%c/%d/%Y',\n",
-      "                             'example': '01/30/2022',\n",
-      "                             'has_time': False,\n",
-      "                             'id': 4,\n",
-      "                             'unix_format': 'yyyy-MM-dd'},\n",
-      "                            {'created_at': datetime.datetime(2022, 7, 26, 13, 1, 15, 762000, tzinfo=tzutc()),\n",
-      "                             'database_format': '%c/%d/%y',\n",
-      "                             'example': '01/30/22',\n",
-      "                             'has_time': False,\n",
-      "                             'id': 5,\n",
-      "                             'unix_format': 'yyyy-MM-dd'},\n",
-      "                            {'created_at': datetime.datetime(2022, 7, 26, 13, 1, 15, 765000, tzinfo=tzutc()),\n",
-      "                             'database_format': '%Y-%c-%d %H:%i:%S.%f',\n",
-      "                             'example': '2022-01-30 13:44:25.0',\n",
-      "                             'has_time': True,\n",
-      "                             'id': 6,\n",
-      "                             'unix_format': 'yyyy-MM-dd HH:mm:ss.SSSSSS'},\n",
-      "                            {'created_at': datetime.datetime(2022, 7, 26, 13, 1, 15, 767000, tzinfo=tzutc()),\n",
-      "                             'database_format': '%Y-%c-%d %H:%i:%S',\n",
-      "                             'example': '2022-01-30 13:44:25',\n",
-      "                             'has_time': True,\n",
-      "                             'id': 7,\n",
-      "                             'unix_format': 'yyyy-MM-dd HH:mm:ss'},\n",
-      "                            {'created_at': datetime.datetime(2022, 7, 26, 13, 1, 15, 770000, tzinfo=tzutc()),\n",
-      "                             'database_format': '%d.%c.%Y %H:%i:%S',\n",
-      "                             'example': '30.01.2022 13:44:25',\n",
-      "                             'has_time': True,\n",
-      "                             'id': 8,\n",
-      "                             'unix_format': 'dd.MM.yyyy HH:mm:ss'}],\n",
-      "           'default_port': 3306,\n",
-      "           'dialect': 'org.hibernate.dialect.MariaDBDialect',\n",
-      "           'driver_class': 'org.mariadb.jdbc.Driver',\n",
-      "           'environment': [{'iid': 1,\n",
-      "                            'key': 'ROOT',\n",
-      "                            'type': 'PRIVILEGED_USERNAME',\n",
-      "                            'value': 'root'},\n",
-      "                           {'iid': 1,\n",
-      "                            'key': 'MARIADB_ROOT_PASSWORD',\n",
-      "                            'type': 'PRIVILEGED_PASSWORD',\n",
-      "                            'value': 'mariadb'},\n",
-      "                           {'iid': 1,\n",
-      "                            'key': 'MARIADB_USER',\n",
-      "                            'type': 'USERNAME',\n",
-      "                            'value': 'mariadb'},\n",
-      "                           {'iid': 1,\n",
-      "                            'key': 'MARIADB_PASSWORD',\n",
-      "                            'type': 'PASSWORD',\n",
-      "                            'value': 'mariadb'}],\n",
-      "           'hash': None,\n",
-      "           'id': 1,\n",
-      "           'jdbc_method': 'mariadb',\n",
-      "           'repository': 'mariadb',\n",
-      "           'size': None,\n",
-      "           'tag': '10.5'},\n",
-      " 'internal_name': 'airquality',\n",
-      " 'is_public': True,\n",
-      " 'language': None,\n",
-      " 'license': None,\n",
-      " 'name': 'Airquality',\n",
-      " 'publication': None,\n",
-      " 'publisher': None,\n",
-      " 'subjects': [],\n",
-      " 'tables': []}\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = database.find_by_id(container_id, database_id)\n",
-    "database_exchange = response.exchange\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Add metadata to database"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 120,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'container': {'created': datetime.datetime(2022, 7, 26, 13, 5, 36, 339000, tzinfo=tzutc()),\n",
-      "               'creator': {'affiliation': None,\n",
-      "                           'authorities': None,\n",
-      "                           'email': 'someone@example.com',\n",
-      "                           'email_verified': False,\n",
-      "                           'firstname': None,\n",
-      "                           'id': 2,\n",
-      "                           'lastname': None,\n",
-      "                           'orcid': None,\n",
-      "                           'theme_dark': False,\n",
-      "                           'titles_after': None,\n",
-      "                           'titles_before': None,\n",
-      "                           'username': 'user'},\n",
-      "               'hash': '5dc114629602472d0bb93f4aedd6a38f161dd59ed129247511c83767fcba0a19',\n",
-      "               'id': 1,\n",
-      "               'internal_name': 'fda-userdb-airquality',\n",
-      "               'is_public': None,\n",
-      "               'name': 'Airquality'},\n",
-      " 'created': datetime.datetime(2022, 7, 26, 13, 5, 42, 453000, tzinfo=tzutc()),\n",
-      " 'creator': {'affiliation': None,\n",
-      "             'authorities': None,\n",
-      "             'email': 'someone@example.com',\n",
-      "             'email_verified': False,\n",
-      "             'firstname': None,\n",
-      "             'id': 2,\n",
-      "             'lastname': None,\n",
-      "             'orcid': None,\n",
-      "             'theme_dark': False,\n",
-      "             'titles_after': None,\n",
-      "             'titles_before': None,\n",
-      "             'username': 'user'},\n",
-      " 'description': 'This dataset includes daily values from 1983 to the current '\n",
-      "                'day, divided into annual files. This includes the maximum '\n",
-      "                'hourly average and the number of times the hourly average '\n",
-      "                'limit value for ozone was exceeded and the daily averages for '\n",
-      "                'sulfur dioxide (SO2), carbon monoxide (CO), nitrogen oxide '\n",
-      "                '(NOx), nitrogen monoxide (NO), nitrogen dioxide (NO2), '\n",
-      "                'particulate matter (PM10 and PM2.5). ) and particle number '\n",
-      "                '(PN), provided that they are of sufficient quality. The '\n",
-      "                'values of the completed day for the current year are updated '\n",
-      "                'every 30 minutes after midnight (UTC+1).',\n",
-      " 'engine': 'mariadb:10.5',\n",
-      " 'id': 1,\n",
-      " 'is_public': True,\n",
-      " 'name': 'Airquality'}\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = database.update({\n",
-    "    \"description\": \"This dataset includes daily values from 1983 to the current day, divided into annual files. This includes the maximum hourly average and the number of times the hourly average limit value for ozone was exceeded and the daily averages for sulfur dioxide (SO2), carbon monoxide (CO), nitrogen oxide (NOx), nitrogen monoxide (NO), nitrogen dioxide (NO2), particulate matter (PM10 and PM2.5). ) and particle number (PN), provided that they are of sufficient quality. The values of the completed day for the current year are updated every 30 minutes after midnight (UTC+1).\",\n",
-    "    \"publisher\": \"Technical University of Vienna\",\n",
-    "    \"license\": {\n",
-    "        \"identifier\": \"CC0-1.0\",\n",
-    "        \"uri\": \"https://creativecommons.org/publicdomain/zero/1.0/legalcode\"\n",
-    "    },\n",
-    "    \"language\": \"en\",\n",
-    "    \"is_public\": True,\n",
-    "    \"publication\": \"2022-07-19\"\n",
-    "}, container_id, database_id)\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Create table"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 121,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'creator': {'affiliation': None,\n",
-      "             'authorities': None,\n",
-      "             'email': 'someone@example.com',\n",
-      "             'email_verified': False,\n",
-      "             'firstname': None,\n",
-      "             'id': 2,\n",
-      "             'lastname': None,\n",
-      "             'orcid': None,\n",
-      "             'theme_dark': False,\n",
-      "             'titles_after': None,\n",
-      "             'titles_before': None,\n",
-      "             'username': 'user'},\n",
-      " 'id': 1,\n",
-      " 'internal_name': 'airquality_a7a429a6-0ce3-11ed-9462-8c8caada74c3',\n",
-      " 'name': 'Airquality a7a429a6-0ce3-11ed-9462-8c8caada74c3'}\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = table.create({\n",
-    "    \"name\": \"Airquality \" + str(uuid.uuid1()),\n",
-    "    \"description\": \"Airquality in Zürich, Switzerland\",\n",
-    "    \"columns\": [{\n",
-    "        \"name\": \"Date\",\n",
-    "        \"type\": \"date\",\n",
-    "        \"dfid\": 1,\n",
-    "        \"unique\": False,\n",
-    "        \"primary_key\": False,\n",
-    "        \"null_allowed\": True,\n",
-    "    }, {\n",
-    "        \"name\": \"Location\",\n",
-    "        \"type\": \"string\",\n",
-    "        \"unique\": False,\n",
-    "        \"primary_key\": False,\n",
-    "        \"null_allowed\": True,\n",
-    "    }, {\n",
-    "        \"name\": \"Parameter\",\n",
-    "        \"type\": \"string\",\n",
-    "        \"unique\": False,\n",
-    "        \"primary_key\": False,\n",
-    "        \"null_allowed\": True,\n",
-    "    }, {\n",
-    "        \"name\": \"Interval\",\n",
-    "        \"type\": \"string\",\n",
-    "        \"unique\": False,\n",
-    "        \"primary_key\": False,\n",
-    "        \"null_allowed\": True,\n",
-    "    }, {\n",
-    "        \"name\": \"Unit\",\n",
-    "        \"type\": \"string\",\n",
-    "        \"unique\": False,\n",
-    "        \"primary_key\": False,\n",
-    "        \"null_allowed\": True,\n",
-    "    }, {\n",
-    "        \"name\": \"Value\",\n",
-    "        \"type\": \"decimal\",\n",
-    "        \"unique\": False,\n",
-    "        \"primary_key\": False,\n",
-    "        \"null_allowed\": True,\n",
-    "    }, {\n",
-    "        \"name\": \"Status\",\n",
-    "        \"type\": \"string\",\n",
-    "        \"unique\": False,\n",
-    "        \"primary_key\": False,\n",
-    "        \"null_allowed\": True,\n",
-    "    }]\n",
-    "}, container_id, database_id)\n",
-    "table_id = response.id\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Inspect table"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 122,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'columns': [{'auto_generated': True,\n",
-      "              'check_expression': None,\n",
-      "              'column_concept': None,\n",
-      "              'column_type': 'number',\n",
-      "              'date_format': None,\n",
-      "              'decimal_digits_after': None,\n",
-      "              'decimal_digits_before': None,\n",
-      "              'enum_values': [],\n",
-      "              'foreign_key': None,\n",
-      "              'id': 1,\n",
-      "              'internal_name': 'id',\n",
-      "              'is_null_allowed': False,\n",
-      "              'is_primary_key': True,\n",
-      "              'name': 'id',\n",
-      "              'references': None,\n",
-      "              'unique': True},\n",
-      "             {'auto_generated': False,\n",
-      "              'check_expression': None,\n",
-      "              'column_concept': None,\n",
-      "              'column_type': 'date',\n",
-      "              'date_format': {'created_at': datetime.datetime(2022, 7, 26, 13, 1, 15, 747000, tzinfo=tzutc()),\n",
-      "                              'database_format': '%Y-%c-%d',\n",
-      "                              'example': '2022-01-30',\n",
-      "                              'has_time': False,\n",
-      "                              'id': 1,\n",
-      "                              'unix_format': 'yyyy-MM-dd'},\n",
-      "              'decimal_digits_after': None,\n",
-      "              'decimal_digits_before': None,\n",
-      "              'enum_values': [],\n",
-      "              'foreign_key': None,\n",
-      "              'id': 2,\n",
-      "              'internal_name': 'date',\n",
-      "              'is_null_allowed': True,\n",
-      "              'is_primary_key': False,\n",
-      "              'name': 'Date',\n",
-      "              'references': None,\n",
-      "              'unique': False},\n",
-      "             {'auto_generated': False,\n",
-      "              'check_expression': None,\n",
-      "              'column_concept': None,\n",
-      "              'column_type': 'string',\n",
-      "              'date_format': None,\n",
-      "              'decimal_digits_after': None,\n",
-      "              'decimal_digits_before': None,\n",
-      "              'enum_values': [],\n",
-      "              'foreign_key': None,\n",
-      "              'id': 3,\n",
-      "              'internal_name': 'location',\n",
-      "              'is_null_allowed': True,\n",
-      "              'is_primary_key': False,\n",
-      "              'name': 'Location',\n",
-      "              'references': None,\n",
-      "              'unique': False},\n",
-      "             {'auto_generated': False,\n",
-      "              'check_expression': None,\n",
-      "              'column_concept': None,\n",
-      "              'column_type': 'string',\n",
-      "              'date_format': None,\n",
-      "              'decimal_digits_after': None,\n",
-      "              'decimal_digits_before': None,\n",
-      "              'enum_values': [],\n",
-      "              'foreign_key': None,\n",
-      "              'id': 4,\n",
-      "              'internal_name': 'parameter',\n",
-      "              'is_null_allowed': True,\n",
-      "              'is_primary_key': False,\n",
-      "              'name': 'Parameter',\n",
-      "              'references': None,\n",
-      "              'unique': False},\n",
-      "             {'auto_generated': False,\n",
-      "              'check_expression': None,\n",
-      "              'column_concept': None,\n",
-      "              'column_type': 'string',\n",
-      "              'date_format': None,\n",
-      "              'decimal_digits_after': None,\n",
-      "              'decimal_digits_before': None,\n",
-      "              'enum_values': [],\n",
-      "              'foreign_key': None,\n",
-      "              'id': 5,\n",
-      "              'internal_name': 'interval',\n",
-      "              'is_null_allowed': True,\n",
-      "              'is_primary_key': False,\n",
-      "              'name': 'Interval',\n",
-      "              'references': None,\n",
-      "              'unique': False},\n",
-      "             {'auto_generated': False,\n",
-      "              'check_expression': None,\n",
-      "              'column_concept': None,\n",
-      "              'column_type': 'string',\n",
-      "              'date_format': None,\n",
-      "              'decimal_digits_after': None,\n",
-      "              'decimal_digits_before': None,\n",
-      "              'enum_values': [],\n",
-      "              'foreign_key': None,\n",
-      "              'id': 6,\n",
-      "              'internal_name': 'unit',\n",
-      "              'is_null_allowed': True,\n",
-      "              'is_primary_key': False,\n",
-      "              'name': 'Unit',\n",
-      "              'references': None,\n",
-      "              'unique': False},\n",
-      "             {'auto_generated': False,\n",
-      "              'check_expression': None,\n",
-      "              'column_concept': None,\n",
-      "              'column_type': 'decimal',\n",
-      "              'date_format': None,\n",
-      "              'decimal_digits_after': None,\n",
-      "              'decimal_digits_before': None,\n",
-      "              'enum_values': [],\n",
-      "              'foreign_key': None,\n",
-      "              'id': 7,\n",
-      "              'internal_name': 'value',\n",
-      "              'is_null_allowed': True,\n",
-      "              'is_primary_key': False,\n",
-      "              'name': 'Value',\n",
-      "              'references': None,\n",
-      "              'unique': False},\n",
-      "             {'auto_generated': False,\n",
-      "              'check_expression': None,\n",
-      "              'column_concept': None,\n",
-      "              'column_type': 'string',\n",
-      "              'date_format': None,\n",
-      "              'decimal_digits_after': None,\n",
-      "              'decimal_digits_before': None,\n",
-      "              'enum_values': [],\n",
-      "              'foreign_key': None,\n",
-      "              'id': 8,\n",
-      "              'internal_name': 'status',\n",
-      "              'is_null_allowed': True,\n",
-      "              'is_primary_key': False,\n",
-      "              'name': 'Status',\n",
-      "              'references': None,\n",
-      "              'unique': False}],\n",
-      " 'created': datetime.datetime(2022, 7, 26, 13, 5, 43, 660000, tzinfo=tzutc()),\n",
-      " 'description': 'Airquality in Zürich, Switzerland',\n",
-      " 'id': 1,\n",
-      " 'internal_name': 'airquality_a7a429a6-0ce3-11ed-9462-8c8caada74c3',\n",
-      " 'name': 'Airquality a7a429a6-0ce3-11ed-9462-8c8caada74c3',\n",
-      " 'topic': 'airquality_a7a429a6-0ce3-11ed-9462-8c8caada74c3'}\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = table.find_by_id(container_id, database_id, table_id)\n",
-    "table_internal_name = response.internal_name\n",
-    "table_topic = response.topic\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Import .csv"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 123,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "None\n"
-     ]
-    }
-   ],
-   "source": [
-    "shutil.copyfile(os.getcwd() + \"/resources/ugz_ogd_air_h1_2021.csv\", \"/tmp/ugz_ogd_air_h1_2021.csv\")\n",
-    "response = data.import_csv({\n",
-    "    \"location\": \"/tmp/ugz_ogd_air_h1_2021.csv\",\n",
-    "    \"separator\": \",\",\n",
-    "    \"quote\": \"\\\"\",\n",
-    "    \"skip_lines\": 1\n",
-    "}, container_id, database_id, table_id)\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Create subset"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 124,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'id': 1,\n",
-      " 'result': [{'date': '2021-01-01T00:00:00Z',\n",
-      "             'interval': 'h1',\n",
-      "             'location': 'Schimmelstrasse',\n",
-      "             'parameter': 'NOx',\n",
-      "             'status': 'tentative',\n",
-      "             'unit': 'ppb',\n",
-      "             'value': 41.66},\n",
-      "            {'date': '2021-01-01T00:00:00Z',\n",
-      "             'interval': 'h1',\n",
-      "             'location': 'Schimmelstrasse',\n",
-      "             'parameter': 'NO',\n",
-      "             'status': 'tentative',\n",
-      "             'unit': 'µg/m3',\n",
-      "             'value': 21.64},\n",
-      "            {'date': '2021-01-01T00:00:00Z',\n",
-      "             'interval': 'h1',\n",
-      "             'location': 'Schimmelstrasse',\n",
-      "             'parameter': 'NO2',\n",
-      "             'status': 'tentative',\n",
-      "             'unit': 'µg/m3',\n",
-      "             'value': 46.49}],\n",
-      " 'result_number': 52548}\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = query.execute({\n",
-    "    \"statement\": \"select `date`, `location`, `parameter`, `interval`, `unit`, `value`, `status` from `\" + table_internal_name + \"` where `location` = 'Schimmelstrasse'\"\n",
-    "}, container_id, database_id, page=0, size=3)\n",
-    "query_id = response.id\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Create invalid subset"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 125,
-   "outputs": [
-    {
-     "ename": "ApiException",
-     "evalue": "(400)\nReason: Bad Request\nHTTP response headers: HTTPHeaderDict({'transfer-encoding': 'chunked', 'Vary': 'Origin, Access-Control-Request-Method, Access-Control-Request-Headers', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block', 'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json', 'Date': 'Tue, 26 Jul 2022 13:05:46 GMT'})\nHTTP response body: b'{\"status\":\"BAD_REQUEST\",\"message\":\"Failed to execute and map time-versioned query\",\"code\":\"error.table.malformed\"}'\n",
-     "output_type": "error",
-     "traceback": [
-      "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
-      "\u001B[0;31mApiException\u001B[0m                              Traceback (most recent call last)",
-      "Input \u001B[0;32mIn [125]\u001B[0m, in \u001B[0;36m<cell line: 1>\u001B[0;34m()\u001B[0m\n\u001B[0;32m----> 1\u001B[0m response \u001B[38;5;241m=\u001B[39m \u001B[43mquery\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mexecute\u001B[49m\u001B[43m(\u001B[49m\u001B[43m{\u001B[49m\n\u001B[1;32m      2\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mstatement\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m:\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mselect `date`, `location`, `parameter`, `interval`, `unit`, `value`, `status` from `\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m \u001B[49m\u001B[38;5;241;43m+\u001B[39;49m\u001B[43m \u001B[49m\u001B[43mtable_internal_name\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m+\u001B[39;49m\u001B[43m \u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43m` where `foo` = \u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43mbar\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\n\u001B[1;32m      3\u001B[0m \u001B[43m}\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcontainer_id\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mdatabase_id\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpage\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43msize\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;241;43m3\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[1;32m      4\u001B[0m \u001B[38;5;28mprint\u001B[39m(response)\n",
-      "File \u001B[0;32m~/Projects/fda-services/.jupyter/api_query/api/query_endpoint_api.py:57\u001B[0m, in \u001B[0;36mQueryEndpointApi.execute\u001B[0;34m(self, body, id, database_id, **kwargs)\u001B[0m\n\u001B[1;32m     55\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mexecute_with_http_info(body, \u001B[38;5;28mid\u001B[39m, database_id, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)  \u001B[38;5;66;03m# noqa: E501\u001B[39;00m\n\u001B[1;32m     56\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m---> 57\u001B[0m     (data) \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mexecute_with_http_info\u001B[49m\u001B[43m(\u001B[49m\u001B[43mbody\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43mid\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mdatabase_id\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43mkwargs\u001B[49m\u001B[43m)\u001B[49m  \u001B[38;5;66;03m# noqa: E501\u001B[39;00m\n\u001B[1;32m     58\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m data\n",
-      "File \u001B[0;32m~/Projects/fda-services/.jupyter/api_query/api/query_endpoint_api.py:140\u001B[0m, in \u001B[0;36mQueryEndpointApi.execute_with_http_info\u001B[0;34m(self, body, id, database_id, **kwargs)\u001B[0m\n\u001B[1;32m    137\u001B[0m \u001B[38;5;66;03m# Authentication setting\u001B[39;00m\n\u001B[1;32m    138\u001B[0m auth_settings \u001B[38;5;241m=\u001B[39m [\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mbearerAuth\u001B[39m\u001B[38;5;124m'\u001B[39m]  \u001B[38;5;66;03m# noqa: E501\u001B[39;00m\n\u001B[0;32m--> 140\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mapi_client\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mcall_api\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m    141\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43m/api/container/\u001B[39;49m\u001B[38;5;132;43;01m{id}\u001B[39;49;00m\u001B[38;5;124;43m/database/\u001B[39;49m\u001B[38;5;132;43;01m{databaseId}\u001B[39;49;00m\u001B[38;5;124;43m/query\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43mPUT\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[1;32m    142\u001B[0m \u001B[43m    \u001B[49m\u001B[43mpath_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    143\u001B[0m \u001B[43m    \u001B[49m\u001B[43mquery_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    144\u001B[0m \u001B[43m    \u001B[49m\u001B[43mheader_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    145\u001B[0m \u001B[43m    \u001B[49m\u001B[43mbody\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mbody_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    146\u001B[0m \u001B[43m    \u001B[49m\u001B[43mpost_params\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mform_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    147\u001B[0m \u001B[43m    \u001B[49m\u001B[43mfiles\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mlocal_var_files\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    148\u001B[0m \u001B[43m    \u001B[49m\u001B[43mresponse_type\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43mQueryResultDto\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m  \u001B[49m\u001B[38;5;66;43;03m# noqa: E501\u001B[39;49;00m\n\u001B[1;32m    149\u001B[0m \u001B[43m    \u001B[49m\u001B[43mauth_settings\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mauth_settings\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    150\u001B[0m \u001B[43m    \u001B[49m\u001B[43masync_req\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mparams\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43masync_req\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    151\u001B[0m \u001B[43m    \u001B[49m\u001B[43m_return_http_data_only\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mparams\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43m_return_http_data_only\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    152\u001B[0m \u001B[43m    \u001B[49m\u001B[43m_preload_content\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mparams\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43m_preload_content\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mTrue\u001B[39;49;00m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    153\u001B[0m \u001B[43m    \u001B[49m\u001B[43m_request_timeout\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mparams\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43m_request_timeout\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    154\u001B[0m \u001B[43m    \u001B[49m\u001B[43mcollection_formats\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mcollection_formats\u001B[49m\u001B[43m)\u001B[49m\n",
-      "File \u001B[0;32m~/Projects/fda-services/.jupyter/api_query/api_client.py:316\u001B[0m, in \u001B[0;36mApiClient.call_api\u001B[0;34m(self, resource_path, method, path_params, query_params, header_params, body, post_params, files, response_type, auth_settings, async_req, _return_http_data_only, collection_formats, _preload_content, _request_timeout)\u001B[0m\n\u001B[1;32m    279\u001B[0m \u001B[38;5;124;03m\"\"\"Makes the HTTP request (synchronous) and returns deserialized data.\u001B[39;00m\n\u001B[1;32m    280\u001B[0m \n\u001B[1;32m    281\u001B[0m \u001B[38;5;124;03mTo make an async request, set the async_req parameter.\u001B[39;00m\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m    313\u001B[0m \u001B[38;5;124;03m    then the method will return the response directly.\u001B[39;00m\n\u001B[1;32m    314\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m    315\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m async_req:\n\u001B[0;32m--> 316\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m__call_api\u001B[49m\u001B[43m(\u001B[49m\u001B[43mresource_path\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmethod\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    317\u001B[0m \u001B[43m                           \u001B[49m\u001B[43mpath_params\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mquery_params\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mheader_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    318\u001B[0m \u001B[43m                           \u001B[49m\u001B[43mbody\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpost_params\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mfiles\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    319\u001B[0m \u001B[43m                           \u001B[49m\u001B[43mresponse_type\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mauth_settings\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    320\u001B[0m \u001B[43m                           \u001B[49m\u001B[43m_return_http_data_only\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcollection_formats\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    321\u001B[0m \u001B[43m                           \u001B[49m\u001B[43m_preload_content\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43m_request_timeout\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m    322\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m    323\u001B[0m     thread \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mpool\u001B[38;5;241m.\u001B[39mapply_async(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m__call_api, (resource_path,\n\u001B[1;32m    324\u001B[0m                                    method, path_params, query_params,\n\u001B[1;32m    325\u001B[0m                                    header_params, body,\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m    329\u001B[0m                                    collection_formats,\n\u001B[1;32m    330\u001B[0m                                    _preload_content, _request_timeout))\n",
-      "File \u001B[0;32m~/Projects/fda-services/.jupyter/api_query/api_client.py:148\u001B[0m, in \u001B[0;36mApiClient.__call_api\u001B[0;34m(self, resource_path, method, path_params, query_params, header_params, body, post_params, files, response_type, auth_settings, _return_http_data_only, collection_formats, _preload_content, _request_timeout)\u001B[0m\n\u001B[1;32m    145\u001B[0m url \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mconfiguration\u001B[38;5;241m.\u001B[39mhost \u001B[38;5;241m+\u001B[39m resource_path\n\u001B[1;32m    147\u001B[0m \u001B[38;5;66;03m# perform request and return response\u001B[39;00m\n\u001B[0;32m--> 148\u001B[0m response_data \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mrequest\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m    149\u001B[0m \u001B[43m    \u001B[49m\u001B[43mmethod\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mquery_params\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mquery_params\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mheaders\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mheader_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    150\u001B[0m \u001B[43m    \u001B[49m\u001B[43mpost_params\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mpost_params\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mbody\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mbody\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    151\u001B[0m \u001B[43m    \u001B[49m\u001B[43m_preload_content\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m_preload_content\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    152\u001B[0m \u001B[43m    \u001B[49m\u001B[43m_request_timeout\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m_request_timeout\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m    154\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mlast_response \u001B[38;5;241m=\u001B[39m response_data\n\u001B[1;32m    156\u001B[0m return_data \u001B[38;5;241m=\u001B[39m response_data\n",
-      "File \u001B[0;32m~/Projects/fda-services/.jupyter/api_query/api_client.py:366\u001B[0m, in \u001B[0;36mApiClient.request\u001B[0;34m(self, method, url, query_params, headers, post_params, body, _preload_content, _request_timeout)\u001B[0m\n\u001B[1;32m    358\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mrest_client\u001B[38;5;241m.\u001B[39mPOST(url,\n\u001B[1;32m    359\u001B[0m                                  query_params\u001B[38;5;241m=\u001B[39mquery_params,\n\u001B[1;32m    360\u001B[0m                                  headers\u001B[38;5;241m=\u001B[39mheaders,\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m    363\u001B[0m                                  _request_timeout\u001B[38;5;241m=\u001B[39m_request_timeout,\n\u001B[1;32m    364\u001B[0m                                  body\u001B[38;5;241m=\u001B[39mbody)\n\u001B[1;32m    365\u001B[0m \u001B[38;5;28;01melif\u001B[39;00m method \u001B[38;5;241m==\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mPUT\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[0;32m--> 366\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mrest_client\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mPUT\u001B[49m\u001B[43m(\u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    367\u001B[0m \u001B[43m                                \u001B[49m\u001B[43mquery_params\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mquery_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    368\u001B[0m \u001B[43m                                \u001B[49m\u001B[43mheaders\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mheaders\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    369\u001B[0m \u001B[43m                                \u001B[49m\u001B[43mpost_params\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mpost_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    370\u001B[0m \u001B[43m                                \u001B[49m\u001B[43m_preload_content\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m_preload_content\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    371\u001B[0m \u001B[43m                                \u001B[49m\u001B[43m_request_timeout\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m_request_timeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    372\u001B[0m \u001B[43m                                \u001B[49m\u001B[43mbody\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mbody\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m    373\u001B[0m \u001B[38;5;28;01melif\u001B[39;00m method \u001B[38;5;241m==\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mPATCH\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[1;32m    374\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mrest_client\u001B[38;5;241m.\u001B[39mPATCH(url,\n\u001B[1;32m    375\u001B[0m                                   query_params\u001B[38;5;241m=\u001B[39mquery_params,\n\u001B[1;32m    376\u001B[0m                                   headers\u001B[38;5;241m=\u001B[39mheaders,\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m    379\u001B[0m                                   _request_timeout\u001B[38;5;241m=\u001B[39m_request_timeout,\n\u001B[1;32m    380\u001B[0m                                   body\u001B[38;5;241m=\u001B[39mbody)\n",
-      "File \u001B[0;32m~/Projects/fda-services/.jupyter/api_query/rest.py:273\u001B[0m, in \u001B[0;36mRESTClientObject.PUT\u001B[0;34m(self, url, headers, query_params, post_params, body, _preload_content, _request_timeout)\u001B[0m\n\u001B[1;32m    271\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mPUT\u001B[39m(\u001B[38;5;28mself\u001B[39m, url, headers\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, query_params\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, post_params\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m    272\u001B[0m         body\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, _preload_content\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m, _request_timeout\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m):\n\u001B[0;32m--> 273\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mrequest\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mPUT\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43murl\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    274\u001B[0m \u001B[43m                        \u001B[49m\u001B[43mheaders\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mheaders\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    275\u001B[0m \u001B[43m                        \u001B[49m\u001B[43mquery_params\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mquery_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    276\u001B[0m \u001B[43m                        \u001B[49m\u001B[43mpost_params\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mpost_params\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    277\u001B[0m \u001B[43m                        \u001B[49m\u001B[43m_preload_content\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m_preload_content\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    278\u001B[0m \u001B[43m                        \u001B[49m\u001B[43m_request_timeout\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m_request_timeout\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m    279\u001B[0m \u001B[43m                        \u001B[49m\u001B[43mbody\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mbody\u001B[49m\u001B[43m)\u001B[49m\n",
-      "File \u001B[0;32m~/Projects/fda-services/.jupyter/api_query/rest.py:222\u001B[0m, in \u001B[0;36mRESTClientObject.request\u001B[0;34m(self, method, url, query_params, headers, body, post_params, _preload_content, _request_timeout)\u001B[0m\n\u001B[1;32m    219\u001B[0m     logger\u001B[38;5;241m.\u001B[39mdebug(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mresponse body: \u001B[39m\u001B[38;5;132;01m%s\u001B[39;00m\u001B[38;5;124m\"\u001B[39m, r\u001B[38;5;241m.\u001B[39mdata)\n\u001B[1;32m    221\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;241m200\u001B[39m \u001B[38;5;241m<\u001B[39m\u001B[38;5;241m=\u001B[39m r\u001B[38;5;241m.\u001B[39mstatus \u001B[38;5;241m<\u001B[39m\u001B[38;5;241m=\u001B[39m \u001B[38;5;241m299\u001B[39m:\n\u001B[0;32m--> 222\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m ApiException(http_resp\u001B[38;5;241m=\u001B[39mr)\n\u001B[1;32m    224\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m r\n",
-      "\u001B[0;31mApiException\u001B[0m: (400)\nReason: Bad Request\nHTTP response headers: HTTPHeaderDict({'transfer-encoding': 'chunked', 'Vary': 'Origin, Access-Control-Request-Method, Access-Control-Request-Headers', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block', 'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json', 'Date': 'Tue, 26 Jul 2022 13:05:46 GMT'})\nHTTP response body: b'{\"status\":\"BAD_REQUEST\",\"message\":\"Failed to execute and map time-versioned query\",\"code\":\"error.table.malformed\"}'\n"
-     ]
-    }
-   ],
-   "source": [
-    "response = query.execute({\n",
-    "    \"statement\": \"select `date`, `location`, `parameter`, `interval`, `unit`, `value`, `status` from `\" + table_internal_name + \"` where `foo` = 'bar'\"\n",
-    "}, container_id, database_id, page=0, size=3)\n",
-    "print(response)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.10.4"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
\ No newline at end of file
diff --git a/fda-authentication-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java b/fda-authentication-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
index aa3e3a1cf0c1bb564942a7ddbe6d877ca72f0dae..0ea6bd53e646275bfa3e38c1cde19f7c9bfb3532 100644
--- a/fda-authentication-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
+++ b/fda-authentication-service/rest-service/src/main/java/at/tuwien/endpoints/UserEndpoint.java
@@ -155,6 +155,17 @@ public class UserEndpoint {
                 .body(userMapper.userToUserDto(entity));
     }
 
+    @PutMapping("/{id}/theme")
+    @Transactional
+    @PreAuthorize("hasPermission(#id, 'UPDATE_THEME')")
+    @Operation(summary = "Update user theme", security = @SecurityRequirement(name = "bearerAuth"))
+    public ResponseEntity<Void> updateTheme(@NotNull @PathVariable("id") Long id,
+                                               @NotNull @Valid @RequestBody UserThemeSetDto data) throws UserNotFoundException {
+        userService.updateTheme(id, data);
+        return ResponseEntity.accepted()
+                .build();
+    }
+
     @PutMapping("/{id}/password")
     @Transactional
     @PreAuthorize("hasRole('ROLE_DEVELOPER') or hasPermission(#id, 'UPDATE_PASSWORD')")
diff --git a/fda-authentication-service/services/src/main/java/at/tuwien/service/UserService.java b/fda-authentication-service/services/src/main/java/at/tuwien/service/UserService.java
index d7877d78a2494ffcb6e9274b3dd705299437c9a2..695ff08f25832da78fe5d1e15cd5a5675d647df4 100644
--- a/fda-authentication-service/services/src/main/java/at/tuwien/service/UserService.java
+++ b/fda-authentication-service/services/src/main/java/at/tuwien/service/UserService.java
@@ -88,6 +88,15 @@ public interface UserService {
     User updateRoles(Long id, UserRolesDto data)
             throws UserNotFoundException, RoleNotFoundException, RoleUniqueException;
 
+    /**
+     * Sets the theme for the provided user.
+     *
+     * @param id   The user id.
+     * @param data The theme.
+     * @throws UserNotFoundException The user was not found.
+     */
+    void updateTheme(Long id, UserThemeSetDto data) throws UserNotFoundException;
+
     /**
      * Updates a user with the given id and updated password.
      *
diff --git a/fda-authentication-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java b/fda-authentication-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
index e508c53cbd3ad921afb8af81567862f114d3581d..4ab0e32aa20abd20574fa5d752336041d9aa02a1 100644
--- a/fda-authentication-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
+++ b/fda-authentication-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java
@@ -19,7 +19,6 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.validation.ConstraintViolationException;
-import java.security.Principal;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
@@ -212,6 +211,18 @@ public class UserServiceImpl implements UserService {
         return entity;
     }
 
+    @Override
+    @Transactional
+    public void updateTheme(Long id, UserThemeSetDto data) throws UserNotFoundException {
+        /* check */
+        final User user = find(id);
+        /* save */
+        user.setThemeDark(data.getThemeDark());
+        final User entity = userRepository.save(user);
+        log.info("Updated user with id {}", entity.getId());
+        log.debug("updated user {}", entity);
+    }
+
     @Override
     @Transactional
     public User updatePassword(Long id, UserPasswordDto data) throws UserNotFoundException {
diff --git a/fda-identifier-service/services/src/main/java/at/tuwien/gateway/QueryServiceGateway.java b/fda-identifier-service/services/src/main/java/at/tuwien/gateway/QueryServiceGateway.java
index 715611d99b4e860c9c2ad919f5c7157f3098aca6..aadd8f21329f157e70b42f972a578eb7a4ac08cc 100644
--- a/fda-identifier-service/services/src/main/java/at/tuwien/gateway/QueryServiceGateway.java
+++ b/fda-identifier-service/services/src/main/java/at/tuwien/gateway/QueryServiceGateway.java
@@ -21,6 +21,5 @@ public interface QueryServiceGateway {
      * @throws RemoteUnavailableException The remote service is not available.
      */
     QueryDto find(Long containerId, Long databaseId, IdentifierCreateDto identifier, String authorization)
-            throws QueryNotFoundException,
-            RemoteUnavailableException;
+            throws QueryNotFoundException, RemoteUnavailableException;
 }
diff --git a/fda-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java b/fda-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
index f96736a2e8c772446a74cb099d8e75b17873464f..6058d35080688b094666b947385dd2a986ac3b7d 100644
--- a/fda-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
+++ b/fda-identifier-service/services/src/main/java/at/tuwien/service/impl/IdentifierServiceImpl.java
@@ -126,6 +126,7 @@ public class IdentifierServiceImpl implements IdentifierService {
                         relatedIdentifierRepository.save(id);
                     });
         }
+        entity.setQueryNormalized(query.getQueryNormalized());
         final Identifier identifier = identifierRepository.save(entity);
         log.info("Created identifier with id {}", identifier.getId());
         log.debug("created identifier {}", identifier);
diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserBriefDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserBriefDto.java
index 1b27ee0e2228c2aafb310611f148bfb1d1aa1aa9..464843d2fb8cc14872dda8b624c1a9d3d7aa688f 100644
--- a/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserBriefDto.java
+++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserBriefDto.java
@@ -1,12 +1,10 @@
 package at.tuwien.api.user;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.v3.oas.annotations.Parameter;
 import lombok.*;
 
 import javax.validation.constraints.NotNull;
-import java.util.List;
 
 @Getter
 @Setter
@@ -20,10 +18,6 @@ public class UserBriefDto {
     @Parameter(name = "id")
     private Long id;
 
-    @ToString.Exclude
-    @Parameter(name = "user authorities")
-    private List<GrantedAuthorityDto> authorities;
-
     @NotNull
     @Parameter(name = "user name")
     private String username;
@@ -53,12 +47,4 @@ public class UserBriefDto {
     @Parameter(name = "theme dark")
     private Boolean themeDark;
 
-    @NotNull
-    @Parameter(name = "mail address")
-    private String email;
-
-    @JsonProperty("email_verified")
-    @Parameter(name = "mail address verified")
-    private Boolean emailVerified;
-
 }
diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserThemeSetDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserThemeSetDto.java
new file mode 100644
index 0000000000000000000000000000000000000000..e329522dcd5394a849daae10259ae7b135a180e7
--- /dev/null
+++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserThemeSetDto.java
@@ -0,0 +1,22 @@
+package at.tuwien.api.user;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.Parameter;
+import lombok.*;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Getter
+@Setter
+@ToString
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class UserThemeSetDto {
+
+    @NotNull
+    @JsonProperty("theme_dark")
+    @Parameter(name = "theme dark")
+    private Boolean themeDark;
+}
diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserUpdateDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserUpdateDto.java
index ecff2599956860bb4aad94293e721b207c3c6ad4..e7fb05063f277a21a62fd8bf0a4d11764c34d244 100644
--- a/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserUpdateDto.java
+++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/user/UserUpdateDto.java
@@ -37,9 +37,4 @@ public class UserUpdateDto {
     @Parameter(name = "orcid")
     private String orcid;
 
-    @NotNull
-    @JsonProperty("theme_dark")
-    @Parameter(name = "theme dark")
-    private Boolean themeDark;
-
 }
diff --git a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/AbstractEndpoint.java b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/AbstractEndpoint.java
index 65a1b63b168d1df492debd2b7f627e4fabe05bb6..d065595722184c2a426faadf375b7cf385b9c9a0 100644
--- a/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/AbstractEndpoint.java
+++ b/fda-query-service/rest-service/src/main/java/at/tuwien/endpoint/AbstractEndpoint.java
@@ -41,7 +41,7 @@ public abstract class AbstractEndpoint {
             return true;
         }
         /* view-only operations are allowed on public databases */
-        if (database.getIsPublic() && List.of("DATA_EXPORT", "DATA_VIEW", "DATA_HISTORY").contains(permissionCode)) {
+        if (database.getIsPublic() && List.of("DATA_EXPORT", "DATA_VIEW", "DATA_HISTORY", "QUERY_VIEW_ALL").contains(permissionCode)) {
             log.debug("grant permission {} because database is public", permissionCode);
             return true;
         }
@@ -76,7 +76,7 @@ public abstract class AbstractEndpoint {
             return true;
         }
         /* view-only operations are allowed on public databases */
-        if (database.getIsPublic() && List.of("QUERY_VIEW_ALL", "QUERY_VIEW", "QUERY_EXPORT").contains(
+        if (database.getIsPublic() && List.of("QUERY_VIEW_ALL", "QUERY_VIEW", "QUERY_EXPORT", "QUERY_RE_EXECUTE").contains(
                 permissionCode)) {
             log.debug("grant permission {} because database is public", permissionCode);
             return true;
diff --git a/fda-query-service/services/src/main/java/at/tuwien/mapper/StoreMapper.java b/fda-query-service/services/src/main/java/at/tuwien/mapper/StoreMapper.java
index 9fdb2e03a6fdaf53685580d72f488d1e49b749fd..783f2242a4c1d88155e273aa5291469005e0fa40 100644
--- a/fda-query-service/services/src/main/java/at/tuwien/mapper/StoreMapper.java
+++ b/fda-query-service/services/src/main/java/at/tuwien/mapper/StoreMapper.java
@@ -165,6 +165,7 @@ public interface StoreMapper {
                 .lastModified(data.getTimestamp(7) != null ? data.getTimestamp(7)
                         .toInstant() : null)
                 .query(data.getString(8))
+                .queryNormalized(data.getString(8))
                 .queryHash(data.getString(9))
                 .resultHash(data.getString(10) != null ? data.getString(10) : null)
                 .resultNumber(data.getLong(11))
diff --git a/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java b/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java
index 64dd9d603cc3caef2249c0ab4f2fd7da5c2077c1..159549e16c45ac5ab2a31558014db12060945de5 100644
--- a/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java
+++ b/fda-query-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java
@@ -177,9 +177,8 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
     @Override
     @Transactional(readOnly = true)
     public ExportResource findOne(Long containerId, Long databaseId, Long queryId)
-            throws DatabaseNotFoundException, ImageNotSupportedException,
-            ContainerNotFoundException, FileStorageException, QueryStoreException, QueryNotFoundException,
-            QueryMalformedException, DatabaseConnectionException {
+            throws DatabaseNotFoundException, ImageNotSupportedException, FileStorageException, QueryStoreException,
+            QueryNotFoundException, QueryMalformedException, DatabaseConnectionException {
         final String filename = RandomStringUtils.randomAlphabetic(40) + ".csv";
         /* find */
         final Database database = databaseService.find(containerId, databaseId);
@@ -210,8 +209,8 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
     @Override
     @Transactional
     public Long count(Long containerId, Long databaseId, Long tableId, Instant timestamp)
-            throws DatabaseNotFoundException, TableNotFoundException,
-            ImageNotSupportedException, DatabaseConnectionException, QueryMalformedException, QueryStoreException, TableMalformedException {
+            throws DatabaseNotFoundException, TableNotFoundException, ImageNotSupportedException,
+            DatabaseConnectionException, QueryMalformedException, QueryStoreException, TableMalformedException {
         /* find */
         final Database database = databaseService.find(containerId, databaseId);
         final Table table = tableService.find(containerId, databaseId, tableId);
@@ -277,7 +276,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
             for (int i = 0; i < data.getKeys().size(); i++) {
                 preparedStatement.setObject(i, values.get(i));
             }
-        } catch(SQLException e) {
+        } catch (SQLException e) {
             log.error("Failed to delete tuples");
             throw new TableMalformedException("Failed to delete tuples");
         } finally {
@@ -306,7 +305,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService
                     .executeUpdate();
             queryMapper.dropTemporaryTableSQL(connection, table)
                     .executeUpdate();
-        } catch(SQLException e) {
+        } catch (SQLException e) {
             log.error("Failed to create/insert/drop temporary table");
             throw new TableMalformedException("Failed to create/insert/drop temporary table");
         } finally {
diff --git a/fda-ui/layouts/default.vue b/fda-ui/layouts/default.vue
index 292f620d62a1a2d506d05a386a85d3f797c0b075..132f3ead0c48c307d6a029fe67fabcd2809bae20 100644
--- a/fda-ui/layouts/default.vue
+++ b/fda-ui/layouts/default.vue
@@ -1,5 +1,5 @@
 <template>
-  <v-app dark>
+  <v-app>
     <v-navigation-drawer v-model="drawer" fixed app>
       <v-img
         contain
@@ -104,6 +104,10 @@ export default {
   data () {
     return {
       drawer: false,
+      user: {
+        theme_dark: null
+      },
+      loadingUser: true,
       items: [
         {
           icon: mdiHome,
@@ -157,9 +161,6 @@ export default {
     username () {
       return this.$store.state.user && this.$store.state.user.username
     },
-    nextTheme () {
-      return this.$vuetify.theme.dark ? 'Light' : 'Dark'
-    },
     container () {
       return this.$store.state.container
     },
@@ -171,15 +172,29 @@ export default {
     },
     db () {
       return this.$store.state.db
+    },
+    config () {
+      if (this.token === null) {
+        return {}
+      }
+      return {
+        headers: { Authorization: `Bearer ${this.token}` }
+      }
     }
   },
   watch: {
     $route () {
       this.loadDB()
+      if (this.token) {
+        this.loadUser()
+          .then(() => this.setTheme())
+      }
     }
   },
   mounted () {
     this.loadDB()
+    this.loadUser()
+      .then(() => this.setTheme())
   },
   methods: {
     logout () {
@@ -197,6 +212,25 @@ export default {
           console.error('Failed to load database', err)
         }
       }
+    },
+    async loadUser () {
+      if (!this.token) {
+        return
+      }
+      try {
+        this.loadingUser = true
+        const res = await this.$axios.put('/api/auth', {}, this.config)
+        console.debug('user data', res.data)
+        this.user = res.data
+      } catch (err) {
+        console.error('user data', err)
+        this.$toast.error('Failed to load user')
+        this.error = true
+      }
+      this.loadingUser = false
+    },
+    setTheme () {
+      this.$vuetify.theme.dark = this.user.theme_dark
     }
   }
 }
diff --git a/fda-ui/pages/container/_container_id/database/_database_id/sql.vue b/fda-ui/pages/container/_container_id/database/_database_id/sql.vue
deleted file mode 100644
index b11cc07697de23ce1e449cfc8276a5a5c2cbb3f8..0000000000000000000000000000000000000000
--- a/fda-ui/pages/container/_container_id/database/_database_id/sql.vue
+++ /dev/null
@@ -1,26 +0,0 @@
-<template>
-  <div>
-    <h3>
-      SQL
-    </h3>
-    ...
-  </div>
-</template>
-<script>
-
-export default {
-  name: 'SQL',
-  components: {
-  },
-  data () {
-    return {}
-  },
-  mounted () {
-  },
-  methods: {
-  }
-}
-</script>
-
-<style>
-</style>
diff --git a/fda-ui/pages/container/index.vue b/fda-ui/pages/container/index.vue
index ab3e7495d41acd87d006a2245be7cba31cebf512..b855d8dda518eb7c6be34c1f82288add90b58321 100644
--- a/fda-ui/pages/container/index.vue
+++ b/fda-ui/pages/container/index.vue
@@ -18,6 +18,7 @@
           <thead>
             <tr>
               <th>Name</th>
+              <th>Visibility</th>
               <th>Engine</th>
               <th>Creator</th>
               <th>Created</th>
@@ -25,7 +26,7 @@
           </thead>
           <tbody>
             <tr v-if="containers.length === 0" aria-readonly="true">
-              <td colspan="4">
+              <td colspan="5">
                 <span v-if="!loading">(no databases)</span>
               </td>
             </tr>
@@ -35,6 +36,13 @@
               class="database"
               @click="loadDatabase(item)">
               <td>{{ item.name }}</td>
+              <td>
+                <v-skeleton-loader v-if="!item.database" type="text" width="50" class="mt-1" />
+                <span v-if="item.database">
+                  <span v-if="item.database.is_public">Public</span>
+                  <span v-if="!item.database.is_public">Private <v-icon right>mdi-eye-off</v-icon></span>
+                </span>
+              </td>
               <td>
                 <span v-if="item.database">{{ item.database.engine }}</span>
                 <v-skeleton-loader v-if="!item.database" type="text" width="100" class="mt-1" />
diff --git a/fda-ui/pages/login.vue b/fda-ui/pages/login.vue
index b4eddfafe1a17f9132fa8b374b9419f81d9ab18c..07539ffc0f51a7b1766c21b04db7cec1b7bd1371 100644
--- a/fda-ui/pages/login.vue
+++ b/fda-ui/pages/login.vue
@@ -87,10 +87,9 @@ export default {
       this.$refs.form.validate()
     },
     async login () {
-      const url = '/api/auth'
       try {
         this.loading = true
-        const res = await this.$axios.post(url, this.loginAccount)
+        const res = await this.$axios.post('/api/auth', this.loginAccount)
         console.debug('login user', res.data)
         this.$store.commit('SET_TOKEN', res.data.token)
         const user = { ...res.data }
diff --git a/fda-ui/pages/user/index.vue b/fda-ui/pages/user/index.vue
index b90d1ffd8403ef33c4ab6700f810435462e54135..b6222f1bf74cf28538e4c13abfbf338be915f513 100644
--- a/fda-ui/pages/user/index.vue
+++ b/fda-ui/pages/user/index.vue
@@ -114,14 +114,6 @@
                 label="ORCID" />
             </v-col>
           </v-row>
-          <v-row dense>
-            <v-col cols="5">
-              <v-switch
-                v-model="user.theme_dark"
-                inset
-                label="Dark Mode" />
-            </v-col>
-          </v-row>
           <v-row dense>
             <v-col cols="5">
               <v-btn
@@ -164,6 +156,23 @@
           <pre>{{ $refs.form3 }}</pre>
         </v-form>
       </v-card-text>
+      <v-divider />
+      <v-card-title>Theme</v-card-title>
+      <v-card-text>
+        <v-form v-model="valid4" @submit.prevent="submit">
+          <v-row dense>
+            <v-col cols="5">
+              <v-switch
+                v-model="user.theme_dark"
+                inset
+                label="Dark Mode"
+                :disabled="error"
+                :loading="loadingTheme"
+                @click="toggleTheme" />
+            </v-col>
+          </v-row>
+        </v-form>
+      </v-card-text>
     </v-card>
     <v-breadcrumbs :items="items" class="pa-0 mt-2" />
   </div>
@@ -198,6 +207,7 @@ export default {
         { text: 'Databases', to: '/container', activeClass: '' }
       ],
       loading: false,
+      loadingTheme: false,
       error: false
     }
   },
@@ -275,7 +285,7 @@ export default {
     async changePassword () {
       try {
         this.loading = true
-        const res = await this.$axios.put('/api/user/' + this.user.id + '/password', this.reset, this.config)
+        const res = await this.$axios.put(`/api/user/${this.user.id}/password`, this.reset, this.config)
         console.debug('password', res.data)
         this.error = false
         this.$toast.success('Successfully changed the password')
@@ -288,7 +298,7 @@ export default {
     async updateInfo () {
       try {
         this.loading = true
-        const res = await this.$axios.put('/api/user/' + this.user.id, {
+        const res = await this.$axios.put(`/api/user/${this.user.id}`, {
           titles_before: this.user.titles_before,
           titles_after: this.user.titles_after,
           firstname: this.user.firstname,
@@ -305,6 +315,24 @@ export default {
         this.error = true
       }
       this.loading = false
+    },
+    async toggleTheme () {
+      if (this.loading) {
+        return
+      }
+      try {
+        this.loadingTheme = true
+        const res = await this.$axios.put(`/api/user/${this.user.id}/theme`, {
+          theme_dark: this.user.theme_dark
+        }, this.config)
+        console.debug('theme set', res.data)
+        this.$vuetify.theme.dark = this.user.theme_dark
+      } catch (err) {
+        console.error('theme set', err)
+        this.$toast.error('Failed to update theme')
+        this.error = true
+      }
+      this.loadingTheme = false
     }
   }
 }