diff --git a/neutron_lib/db/model_query.py b/neutron_lib/db/model_query.py index 18c74bc1b..25bee229f 100644 --- a/neutron_lib/db/model_query.py +++ b/neutron_lib/db/model_query.py @@ -19,8 +19,10 @@ from oslo_db.sqlalchemy import utils as sa_utils from sqlalchemy import sql, or_, and_ from sqlalchemy.ext import associationproxy +from neutron_lib._i18n import _ from neutron_lib.api import attributes from neutron_lib.db import utils as db_utils +from neutron_lib import exceptions as n_exc from neutron_lib.objects import utils as obj_utils from neutron_lib.utils import helpers @@ -95,14 +97,23 @@ def get_hooks(model): return _model_query_hooks.get(model, {}).values() -def query_with_hooks(context, model): +def query_with_hooks(context, model, field=None): """Query with hooks using the said context and model. :param context: The context to use for the DB session. :param model: The model to query. + :param field: The column. :returns: The query with hooks applied to it. """ - query = context.session.query(model) + if field: + if hasattr(model, field): + field = getattr(model, field) + else: + msg = _("'%s' is not supported as field") % field + raise n_exc.InvalidInput(error_message=msg) + query = context.session.query(field) + else: + query = context.session.query(model) # define basic filter condition for model query query_filter = None if db_utils.model_query_scope_is_project(context, model): @@ -301,6 +312,12 @@ def get_collection(context, model, dict_func, return items +def get_values(context, model, field, filters=None): + query = query_with_hooks(context, model, field=field) + query = apply_filters(query, model, filters, context) + return [c[0] for c in query] + + def get_collection_count(context, model, filters=None): """Get the count for a specific collection. diff --git a/neutron_lib/tests/unit/db/test_model_query.py b/neutron_lib/tests/unit/db/test_model_query.py index 5e4626591..b99b599fb 100644 --- a/neutron_lib/tests/unit/db/test_model_query.py +++ b/neutron_lib/tests/unit/db/test_model_query.py @@ -56,3 +56,15 @@ class TestHooks(_base.BaseTestCase): self.assertEqual(hook_ref, d.get(k)) else: self.assertEqual({}, d.get(k)) + + def test_get_values(self): + mock_model = mock.Mock() + mock_context = mock.Mock() + with mock.patch.object( + model_query, 'query_with_hooks') as query_with_hooks: + query_with_hooks.return_value = [['value1'], ['value2']] + values = model_query.get_values(mock_context, mock_model, + 'fake_field') + self.assertEqual(['value1', 'value2'], values) + query_with_hooks.assert_called_with( + mock_context, mock_model, field='fake_field') diff --git a/releasenotes/notes/add-support-for-fetching-specific-column-in-OVO-81b764b203849776.yaml b/releasenotes/notes/add-support-for-fetching-specific-column-in-OVO-81b764b203849776.yaml new file mode 100644 index 000000000..82fed9686 --- /dev/null +++ b/releasenotes/notes/add-support-for-fetching-specific-column-in-OVO-81b764b203849776.yaml @@ -0,0 +1,9 @@ +--- +features: + - | + Add method ``get_values`` in ``neutron_lib.db.model_query``. + This method allow callers to fetch specific column from + a database model. + Add keyword parameter ``field`` to method ``query_with_hooks``. + The default value of this parameter is None. + Callers can set this parameter to query specific column.