diff options
author | Timofey Durakov <tdurakov@mirantis.com> | 2015-03-06 17:09:38 +0300 |
---|---|---|
committer | Timofey Durakov <tdurakov@mirantis.com> | 2015-03-14 15:39:51 +0300 |
commit | fa2a6afe7639726fad201a51832b8fcb06c95a75 (patch) | |
tree | f097dbd46e2fda5b9d633ef58126488a41a31fab /nova | |
parent | 2c1784f150026c7b903fc920d480898ff51c424d (diff) | |
download | nova-fa2a6afe7639726fad201a51832b8fcb06c95a75.tar.gz |
Fixed archiving of deleted records
Added specific column order for insert clause
in insert from select query, used in archivation.
Changed source for tables metadata from db to models.
Change-Id: Idff93ab4fa3397746999a836de54354235919471
Closes-Bug: #1431571
Diffstat (limited to 'nova')
-rw-r--r-- | nova/db/sqlalchemy/api.py | 26 | ||||
-rw-r--r-- | nova/tests/unit/db/test_db_api.py | 14 |
2 files changed, 22 insertions, 18 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index dc3dc4c25b..eb11b41bcc 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -5837,8 +5837,12 @@ def archive_deleted_rows_for_table(context, tablename, max_rows): conn = engine.connect() metadata = MetaData() metadata.bind = engine - table = Table(tablename, metadata, autoload=True) - default_deleted_value = _get_default_deleted_value(table) + # NOTE(tdurakov): table metadata should be received + # from models, not db tables. Default value specified by SoftDeleteMixin + # is known only by models, not DB layer. + # IMPORTANT: please do not change source of metadata information for table. + table = models.BASE.metadata.tables[tablename] + shadow_tablename = _SHADOW_TABLE_PREFIX + tablename rows_archived = 0 try: @@ -5853,22 +5857,24 @@ def archive_deleted_rows_for_table(context, tablename, max_rows): column = table.c.domain else: column = table.c.id - # NOTE(guochbo): Use InsertFromSelect and DeleteFromSelect to avoid + # NOTE(guochbo): Use DeleteFromSelect to avoid # database's limit of maximum parameter in one SQL statement. - query_insert = sql.select([table], - table.c.deleted != default_deleted_value).\ - order_by(column).limit(max_rows) + deleted_column = table.c.deleted + columns = [c.name for c in table.c] + insert = shadow_table.insert(inline=True).\ + from_select(columns, + sql.select([table], + deleted_column != deleted_column.default.arg). + order_by(column).limit(max_rows)) query_delete = sql.select([column], - table.c.deleted != default_deleted_value).\ + deleted_column != deleted_column.default.arg).\ order_by(column).limit(max_rows) - insert_statement = sqlalchemyutils.InsertFromSelect( - shadow_table, query_insert) delete_statement = db_utils.DeleteFromSelect(table, query_delete, column) try: # Group the insert and delete in a transaction. with conn.begin(): - conn.execute(insert_statement) + conn.execute(insert) result_delete = conn.execute(delete_statement) except db_exc.DBError: # TODO(ekudryashova): replace by DBReferenceError when db layer diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index fc42dc79bc..4a92a513b6 100644 --- a/nova/tests/unit/db/test_db_api.py +++ b/nova/tests/unit/db/test_db_api.py @@ -7605,24 +7605,22 @@ class ArchiveTestCase(test.TestCase): self.context = context.get_admin_context() self.engine = get_engine() self.conn = self.engine.connect() - self.instance_id_mappings = sqlalchemyutils.get_table( - self.engine, "instance_id_mappings") + self.instance_id_mappings = models.InstanceIdMapping.__table__ self.shadow_instance_id_mappings = sqlalchemyutils.get_table( self.engine, "shadow_instance_id_mappings") - self.dns_domains = sqlalchemyutils.get_table( - self.engine, "dns_domains") + self.dns_domains = models.DNSDomain.__table__ self.shadow_dns_domains = sqlalchemyutils.get_table( self.engine, "shadow_dns_domains") - self.consoles = sqlalchemyutils.get_table(self.engine, "consoles") - self.console_pools = sqlalchemyutils.get_table( - self.engine, "console_pools") + self.consoles = models.Console.__table__ self.shadow_consoles = sqlalchemyutils.get_table( self.engine, "shadow_consoles") + self.console_pools = models.ConsolePool.__table__ self.shadow_console_pools = sqlalchemyutils.get_table( self.engine, "shadow_console_pools") - self.instances = sqlalchemyutils.get_table(self.engine, "instances") + self.instances = models.Instance.__table__ self.shadow_instances = sqlalchemyutils.get_table( self.engine, "shadow_instances") + self.uuidstrs = [] for unused in range(6): self.uuidstrs.append(stdlib_uuid.uuid4().hex) |