Repository: ckan/ckan

Issue:
Failures when initializing the database
**CKAN version**
2.9.4

**Describe the bug**

First run:
```
ckan          | 2021-10-01 10:39:30,892 INFO  [ckan.config.environment] Loading templates from /usr/lib/ckan/venv/src/ckan/ckan/templates
db            | 2021-10-01 10:39:30.906 UTC [118] ERROR:  relation "user" does not exist at character 515
db            | 2021-10-01 10:39:30.906 UTC [118] STATEMENT:  SELECT "user".password AS user_password, "user".id AS user_id, "user".name AS user_name, "user".fullname AS user_fullname, "user".email AS user_email, "user".apikey AS user_apikey, "user".created AS user_created, "user".reset_key AS user_reset_key, "user".about AS user_about, "user".activity_streams_email_notifications AS user_activity_streams_email_notifications, "user".sysadmin AS user_sysadmin, "user".state AS user_state, "user".image_url AS user_image_url, "user".plugin_extras AS user_plugin_extras 
db            | 	FROM "user" 
db            | 	WHERE "user".name = 'default' OR "user".id = 'default' ORDER BY "user".name 
db            | 	 LIMIT 1
ckan          | 2021-10-01 10:39:32,945 INFO  [ckan.cli.db] Initialize the Database
db            | 2021-10-01 10:39:32.946 UTC [119] ERROR:  relation "migrate_version" does not exist at character 21
db            | 2021-10-01 10:39:32.946 UTC [119] STATEMENT:  select version from migrate_version
ckan          | 2021-10-01 10:39:35,534 INFO  [ckan.model] CKAN database version upgraded: base -> ccd38ad5fced (head)
ckan          | 2021-10-01 10:39:35,534 INFO  [ckan.model] Database initialised
ckan          | Initialising DB: SUCCESS
```

Second run:
```
ckan          | 2021-10-01 10:41:26,508 INFO  [ckan.cli.db] Initialize the Database
db            | 2021-10-01 10:41:26.509 UTC [37] ERROR:  relation "migrate_version" does not exist at character 21
db            | 2021-10-01 10:41:26.509 UTC [37] STATEMENT:  select version from migrate_version
ckan          | 2021-10-01 10:41:26,625 INFO  [ckan.model] CKAN database version remains as: ccd38ad5fced (head)
ckan          | 2021-10-01 10:41:26,625 INFO  [ckan.model] Database initialised
ckan          | Initialising DB: SUCCESS
```

**Steps to reproduce**
Steps to reproduce the behavior: `docker-compose up; docker-compose down; docker-compose up`

**Expected behavior**
No errors.

**Additional details**
Docker is used.


Discussion:
For what it's worth Iv'e seen this error for a while now...for me (and my simple testing) it seems benign but I'm not sure....this will get discussed in next Tuesday's Dev meeting

It does not seem to affect CKAN, but it would be nice to avoid having it, as log monitoring tools will always see an "ERROR" popping up from time to time.
Thanks! :)
These are benign, but if someone wants to try to suppress them they should review the Docker entrypoint scripts to see what commands are emitting and try to figure out why there are being shown. 

This one `ERROR:  relation "migrate_version" does not exist at character 21` is being generated [here](https://github.com/ckan/ckan/blob/a226a70019d850683ac77abe5a9df9bde2c2f0a4/ckan/model/__init__.py#L266) when we are checking if the old versioning system is present.

Resolving patch:
diff --git a/ckan/config/environment.py b/ckan/config/environment.py
--- a/ckan/config/environment.py
+++ b/ckan/config/environment.py
@@ -9,7 +9,7 @@
 
 from typing import Union, cast
 
-import sqlalchemy
+from sqlalchemy import engine_from_config, inspect
 import sqlalchemy.exc
 
 import ckan.model as model
@@ -220,7 +220,7 @@ def update_config() -> None:
     # to eliminate database errors due to stale pooled connections
     config.setdefault('sqlalchemy.pool_pre_ping', True)
     # Initialize SQLAlchemy
-    engine = sqlalchemy.engine_from_config(config)
+    engine = engine_from_config(config)
     model.init_model(engine)
 
     for plugin in p.PluginImplementations(p.IConfigurable):
@@ -232,14 +232,18 @@ def update_config() -> None:
     authz.clear_auth_functions_cache()
 
     # Here we create the site user if they are not already in the database
+    user_table_exists = False
     try:
-        logic.get_action('get_site_user')({'ignore_auth': True}, {})
-    except (sqlalchemy.exc.ProgrammingError, sqlalchemy.exc.OperationalError):
-        # The database is not yet initialised. It happens in `ckan db init`
-        pass
-    except sqlalchemy.exc.IntegrityError:
-        # Race condition, user already exists.
-        pass
+        user_table_exists = inspect(engine).has_table("user")
+    except sqlalchemy.exc.OperationalError:
+        log.debug("DB user table does not exist")
+
+    if user_table_exists:
+        try:
+            logic.get_action('get_site_user')({'ignore_auth': True}, {})
+        except sqlalchemy.exc.IntegrityError:
+            # Race condition, user already exists.
+            log.debug("Site user already exists")
 
     # Close current session and open database connections to ensure a clean
     # clean environment even if an error occurs later on
diff --git a/ckan/model/__init__.py b/ckan/model/__init__.py
--- a/ckan/model/__init__.py
+++ b/ckan/model/__init__.py
@@ -8,8 +8,7 @@
 from time import sleep
 from typing import Any, Optional
 
-from sqlalchemy import MetaData, Table
-from sqlalchemy.exc import ProgrammingError
+from sqlalchemy import MetaData, Table, inspect
 
 from alembic.command import (
     upgrade as alembic_upgrade,
@@ -278,12 +277,13 @@ def setup_migration_version_control(self) -> None:
         alembic_config.set_main_option(
             "sqlalchemy.url", config.get("sqlalchemy.url")
         )
-        try:
+
+        sqlalchemy_migrate_version = 0
+        db_inspect = inspect(self.metadata.bind)
+        if db_inspect.has_table("migrate_version"):
             sqlalchemy_migrate_version = self.metadata.bind.execute(
                 u'select version from migrate_version'
             ).scalar()
-        except ProgrammingError:
-            sqlalchemy_migrate_version = 0
 
         # this value is used for graceful upgrade from
         # sqlalchemy-migrate to alembic


Test patch: