From 13c21fb3ea589cce143423e3e18ad837227efc89 Mon Sep 17 00:00:00 2001 From: sam Date: Wed, 1 Feb 2023 15:08:57 +0000 Subject: [PATCH] fix: on db & env init ch, check tables exist prior to sql select --- ckan/config/environment.py | 19 +++++++++---------- ckan/model/__init__.py | 10 +++++----- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/ckan/config/environment.py b/ckan/config/environment.py index fae10507f45..940374175e7 100644 --- 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,13 @@ def update_config() -> None: authz.clear_auth_functions_cache() # Here we create the site user if they are not already in the database - 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 + db_inspect = inspect(engine) + if db_inspect.has_table("user"): + try: + logic.get_action('get_site_user')({'ignore_auth': True}, {}) + except sqlalchemy.exc.IntegrityError: + # Race condition, user already exists. + pass # 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 index 686b5ba72c8..4b7595f58e2 100644 --- 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