From 2e716b53f3622ab3f8e44f6c5aa0e062d58386f7 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Tue, 25 Jul 2023 09:56:29 +0100 Subject: [PATCH] db: Enable foreign keys for SQLite backend We were doing this adhoc in tests, which doesn't seem to be possible in SQLAlchemy 2.0. Do it everywhere instead. This highlights a small issue that we have to workaround in the tests. Change-Id: I9dd70c9976f83a00a8cb270422e545ff2c77f12f Signed-off-by: Stephen Finucane --- glance/db/sqlalchemy/api.py | 5 ++++- glance/tests/functional/db/base.py | 29 +++++++++++++++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/glance/db/sqlalchemy/api.py b/glance/db/sqlalchemy/api.py index d880921fc2..40f30149a1 100644 --- a/glance/db/sqlalchemy/api.py +++ b/glance/db/sqlalchemy/api.py @@ -82,7 +82,10 @@ def _create_facade_lazily(): if _FACADE is None: with _LOCK: if _FACADE is None: - _FACADE = oslo_db_session.EngineFacade.from_config(CONF) + _FACADE = oslo_db_session.EngineFacade.from_config( + CONF, + sqlite_fk=True, + ) if CONF.profiler.enabled and CONF.profiler.trace_sqlalchemy: osprofiler.sqlalchemy.add_tracing(sqlalchemy, diff --git a/glance/tests/functional/db/base.py b/glance/tests/functional/db/base.py index 75e7d62f1d..769b8c73f7 100644 --- a/glance/tests/functional/db/base.py +++ b/glance/tests/functional/db/base.py @@ -23,12 +23,13 @@ import uuid from oslo_db import exception as db_exception from oslo_db.sqlalchemy import utils as sqlalchemyutils -from sqlalchemy.dialects import sqlite +from sqlalchemy import sql from glance.common import exception from glance.common import timeutils from glance import context from glance.db.sqlalchemy import api as db_api +from glance.db.sqlalchemy import models from glance.tests import functional import glance.tests.functional.db as db_tests from glance.tests import utils as test_utils @@ -2081,13 +2082,27 @@ class DBPurgeTests(test_utils.BaseTestCase): self.assertEqual(len(tasks), 2) def test_db_purge_images_table(self): + images = self.db_api.image_get_all(self.adm_context) + self.assertEqual(len(images), 3) + tasks = self.db_api.task_get_all(self.adm_context) + self.assertEqual(len(tasks), 3) + + # purge records from locations table + for image in images: + session = self.db_api.get_session() + with session.begin(): + session.execute( + sql.delete(models.ImageLocation) + .where(models.ImageLocation.image_id == image['id']) + ) + # purge records from images_tags table self.db_api.purge_deleted_rows(self.adm_context, 1, 5) # purge records from images table self.db_api.purge_deleted_rows_from_images(self.adm_context, 1, 5) - images = self.db_api.image_get_all(self.adm_context) + images = self.db_api.image_get_all(self.adm_context) self.assertEqual(len(images), 2) tasks = self.db_api.task_get_all(self.adm_context) self.assertEqual(len(tasks), 2) @@ -2102,14 +2117,8 @@ class DBPurgeTests(test_utils.BaseTestCase): engine = db_api.get_engine() connection = engine.connect() - dialect = engine.url.get_dialect() - if dialect == sqlite.dialect: - connection.exec_driver_sql("PRAGMA foreign_keys = ON") - - images = sqlalchemyutils.get_table( - engine, "images") - image_tags = sqlalchemyutils.get_table( - engine, "image_tags") + images = sqlalchemyutils.get_table(engine, "images") + image_tags = sqlalchemyutils.get_table(engine, "image_tags") # Add a 4th row in images table and set it deleted 15 days ago uuidstr = uuid.uuid4().hex