summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nova/db/main/api.py7
-rw-r--r--nova/objects/cell_mapping.py12
-rw-r--r--nova/tests/fixtures/nova.py10
3 files changed, 25 insertions, 4 deletions
diff --git a/nova/db/main/api.py b/nova/db/main/api.py
index 4c40be905e..39775d4f46 100644
--- a/nova/db/main/api.py
+++ b/nova/db/main/api.py
@@ -4176,6 +4176,12 @@ def _get_fk_stmts(metadata, conn, table, column, records):
fk_column = fk_table.c.id
for fk in fk_table.foreign_keys:
+ if table != fk.column.table:
+ # if the foreign key doesn't actually point to the table we're
+ # archiving entries from then it's not relevant; trying to
+ # resolve this would result in a cartesian product
+ continue
+
# We need to find the records in the referring (child) table that
# correspond to the records in our (parent) table so we can archive
# them.
@@ -4225,6 +4231,7 @@ def _get_fk_stmts(metadata, conn, table, column, records):
# deque.
fk_delete = fk_table.delete().where(fk_column.in_(fk_records))
deletes.appendleft(fk_delete)
+
# Repeat for any possible nested child tables.
i, d = _get_fk_stmts(metadata, conn, fk_table, fk_column, fk_records)
inserts.extendleft(i)
diff --git a/nova/objects/cell_mapping.py b/nova/objects/cell_mapping.py
index 595ec43e48..1355182420 100644
--- a/nova/objects/cell_mapping.py
+++ b/nova/objects/cell_mapping.py
@@ -279,11 +279,15 @@ class CellMappingList(base.ObjectListBase, base.NovaObject):
# SELECT DISTINCT cell_id FROM instance_mappings \
# WHERE project_id = $project_id;
cell_ids = context.session.query(
- api_db_models.InstanceMapping.cell_id).filter_by(
- project_id=project_id).distinct().subquery()
+ api_db_models.InstanceMapping.cell_id
+ ).filter_by(
+ project_id=project_id
+ ).distinct()
# SELECT cell_mappings WHERE cell_id IN ($cell_ids);
- return context.session.query(api_db_models.CellMapping).filter(
- api_db_models.CellMapping.id.in_(cell_ids)).all()
+ return context.session.query(
+ api_db_models.CellMapping).filter(
+ api_db_models.CellMapping.id.in_(cell_ids)
+ ).all()
@classmethod
def get_by_project_id(cls, context, project_id):
diff --git a/nova/tests/fixtures/nova.py b/nova/tests/fixtures/nova.py
index 27ca2fd77d..f9e011dd67 100644
--- a/nova/tests/fixtures/nova.py
+++ b/nova/tests/fixtures/nova.py
@@ -904,6 +904,16 @@ class WarningsFixture(fixtures.Fixture):
message='Implicit coercion of SELECT and textual SELECT .*',
category=sqla_exc.SADeprecationWarning)
+ # Enable general SQLAlchemy warnings also to ensure we're not doing
+ # silly stuff. It's possible that we'll need to filter things out here
+ # with future SQLAlchemy versions, but that's a good thing
+
+ warnings.filterwarnings(
+ 'error',
+ module='nova',
+ category=sqla_exc.SAWarning,
+ )
+
self.addCleanup(self._reset_warning_filters)
def _reset_warning_filters(self):