From 00065bd9f62f3a7d033d88243cffe6148b7ee540 Mon Sep 17 00:00:00 2001 From: Eugeniya Kudryashova Date: Fri, 8 Aug 2014 19:16:35 +0300 Subject: [PATCH] Decrease amount of queries while adding aggregate metadata Dict of aggregate metadata sometimes contains a lot of items, so while adding of metadata current implementation make a lot of inserts in database. Using multirow INSERT instead of INSERT statement allows to decrease amount of queries to one single query per operation. Change-Id: I6b842459cf198f8577b615aeba091723dcb18429 --- nova/db/sqlalchemy/api.py | 13 ++++++++----- nova/tests/db/test_db_api.py | 12 ++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index ffc23d1c7132..3401aeead69b 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -5236,14 +5236,17 @@ def aggregate_metadata_add(context, aggregate_id, metadata, set_delete=False, meta_ref.update({"value": metadata[key]}) already_existing_keys.add(key) + new_entries = [] for key, value in metadata.iteritems(): if key in already_existing_keys: continue - meta_ref = models.AggregateMetadata() - meta_ref.update({"key": key, - "value": value, - "aggregate_id": aggregate_id}) - session.add(meta_ref) + new_entries.append({"key": key, + "value": value, + "aggregate_id": aggregate_id}) + if new_entries: + session.execute( + models.AggregateMetadata.__table__.insert(), + new_entries) return metadata except db_exc.DBDuplicateEntry: diff --git a/nova/tests/db/test_db_api.py b/nova/tests/db/test_db_api.py index 8ad651851292..5613c162a040 100644 --- a/nova/tests/db/test_db_api.py +++ b/nova/tests/db/test_db_api.py @@ -578,6 +578,18 @@ class AggregateDBApiTestCase(test.TestCase): expected = db.aggregate_metadata_get(ctxt, result['id']) self.assertThat(metadata, matchers.DictMatches(expected)) + def test_aggregate_metadata_add_and_update(self): + ctxt = context.get_admin_context() + result = _create_aggregate(context=ctxt) + metadata = _get_fake_aggr_metadata() + key = metadata.keys()[0] + new_metadata = {key: 'foo', + 'fake_new_key': 'fake_new_value'} + metadata.update(new_metadata) + db.aggregate_metadata_add(ctxt, result['id'], new_metadata) + expected = db.aggregate_metadata_get(ctxt, result['id']) + self.assertThat(metadata, matchers.DictMatches(expected)) + def test_aggregate_metadata_add_retry(self): ctxt = context.get_admin_context() result = _create_aggregate(context=ctxt, metadata=None)