summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2021-04-28 11:12:59 +0000
committerGerrit Code Review <review@openstack.org>2021-04-28 11:12:59 +0000
commit432ee2f34ecc5ec2582563f552fa4ba0cb1c2584 (patch)
treebb7889132af7eb170b1b3fee64e78bc557fa1bf5
parentca48ef189ee600efadfef01c01035be4cacf2ac6 (diff)
parentf37269ae603bc0e09210379e03a476ff2193c74c (diff)
downloadoslo-db-432ee2f34ecc5ec2582563f552fa4ba0cb1c2584.tar.gz
Merge "Accommodate immutable URL api"
-rw-r--r--oslo_db/sqlalchemy/engines.py12
-rw-r--r--oslo_db/sqlalchemy/provision.py11
-rw-r--r--oslo_db/tests/sqlalchemy/test_exc_filters.py12
-rw-r--r--oslo_db/tests/sqlalchemy/test_sqlalchemy.py20
4 files changed, 46 insertions, 9 deletions
diff --git a/oslo_db/sqlalchemy/engines.py b/oslo_db/sqlalchemy/engines.py
index 25215b9..0e19c18 100644
--- a/oslo_db/sqlalchemy/engines.py
+++ b/oslo_db/sqlalchemy/engines.py
@@ -105,6 +105,14 @@ def _setup_logging(connection_debug=0):
def _extend_url_parameters(url, connection_parameters):
+ # TODO(zzzeek): remove hasattr() conditional when SQLAlchemy 1.4 is the
+ # minimum version in requirements; call update_query_string()
+ # unconditionally
+ if hasattr(url, "update_query_string"):
+ return url.update_query_string(connection_parameters, append=True)
+
+ # TODO(zzzeek): remove the remainder of this method when SQLAlchemy 1.4
+ # is the minimum version in requirements
for key, value in parse.parse_qs(
connection_parameters).items():
if key in url.query:
@@ -118,6 +126,8 @@ def _extend_url_parameters(url, connection_parameters):
if len(value) == 1:
url.query[key] = value[0]
+ return url
+
def _vet_url(url):
if "+" not in url.drivername and not url.drivername.startswith("sqlite"):
@@ -153,7 +163,7 @@ def create_engine(sql_connection, sqlite_fk=False, mysql_sql_mode=None,
url = sqlalchemy.engine.url.make_url(sql_connection)
if connection_parameters:
- _extend_url_parameters(url, connection_parameters)
+ url = _extend_url_parameters(url, connection_parameters)
_vet_url(url)
diff --git a/oslo_db/sqlalchemy/provision.py b/oslo_db/sqlalchemy/provision.py
index 2fc3a54..5addab4 100644
--- a/oslo_db/sqlalchemy/provision.py
+++ b/oslo_db/sqlalchemy/provision.py
@@ -495,7 +495,16 @@ class BackendImpl(object, metaclass=abc.ABCMeta):
"""
url = sa_url.make_url(str(base_url))
- url.database = ident
+
+ # TODO(zzzeek): remove hasattr() conditional in favor of "url.set()"
+ # when SQLAlchemy 1.4 is the minimum version in requirements
+ if hasattr(url, "set"):
+ url = url.set(database=ident)
+ else:
+ # TODO(zzzeek): remove when SQLAlchemy 1.4
+ # is the minimum version in requirements
+ url.database = ident
+
return url
diff --git a/oslo_db/tests/sqlalchemy/test_exc_filters.py b/oslo_db/tests/sqlalchemy/test_exc_filters.py
index b7e0f91..49826e0 100644
--- a/oslo_db/tests/sqlalchemy/test_exc_filters.py
+++ b/oslo_db/tests/sqlalchemy/test_exc_filters.py
@@ -386,8 +386,16 @@ class TestNonExistentDatabase(
super(TestNonExistentDatabase, self).setUp()
url = sqla_url.make_url(str(self.engine.url))
- url.database = 'non_existent_database'
- self.url = url
+
+ # TODO(zzzeek): remove hasattr() conditional in favor of "url.set()"
+ # when SQLAlchemy 1.4 is the minimum version in requirements
+ if hasattr(url, "set"):
+ self.url = url.set(database="non_existent_database")
+ else:
+ # TODO(zzzeek): remove when SQLAlchemy 1.4
+ # is the minimum version in requirements
+ url.database = 'non_existent_database'
+ self.url = url
def test_raise(self):
matched = self.assertRaises(
diff --git a/oslo_db/tests/sqlalchemy/test_sqlalchemy.py b/oslo_db/tests/sqlalchemy/test_sqlalchemy.py
index 8a48eca..7b51e36 100644
--- a/oslo_db/tests/sqlalchemy/test_sqlalchemy.py
+++ b/oslo_db/tests/sqlalchemy/test_sqlalchemy.py
@@ -229,6 +229,16 @@ class QueryParamTest(test_base.DbTestCase):
"oslo_db.sqlalchemy.engines.sqlalchemy.create_engine",
side_effect=_mock_create_engine)
+ def _normalize_query_dict(self, qdict):
+ # SQLAlchemy 1.4 returns url.query as:
+ # immutabledict({k1: v1, k2: (v2a, v2b, ...), ...})
+ # that is with tuples not lists for multiparams
+
+ return {
+ k: list(v) if isinstance(v, tuple) else v
+ for k, v in qdict.items()
+ }
+
def test_add_assorted_params(self):
with self._fixture() as ce:
engines.create_engine(
@@ -236,7 +246,7 @@ class QueryParamTest(test_base.DbTestCase):
connection_parameters="foo=bar&bat=hoho&bat=param2")
self.assertEqual(
- ce.mock_calls[0][1][0].query,
+ self._normalize_query_dict(ce.mock_calls[0][1][0].query),
{'bat': ['hoho', 'param2'], 'foo': 'bar'}
)
@@ -247,7 +257,7 @@ class QueryParamTest(test_base.DbTestCase):
self.assertEqual(
ce.mock_calls[0][1][0].query,
- {}
+ self._normalize_query_dict({})
)
def test_combine_params(self):
@@ -260,7 +270,7 @@ class QueryParamTest(test_base.DbTestCase):
"bind_host=192.168.1.5")
self.assertEqual(
- ce.mock_calls[0][1][0].query,
+ self._normalize_query_dict(ce.mock_calls[0][1][0].query),
{
'bind_host': '192.168.1.5',
'charset': 'utf8',
@@ -280,7 +290,7 @@ class QueryParamTest(test_base.DbTestCase):
"bind_host=192.168.1.5")
self.assertEqual(
- ce.mock_calls[0][1][0].query,
+ self._normalize_query_dict(ce.mock_calls[0][1][0].query),
{
'bind_host': '192.168.1.5',
'charset': 'utf8',
@@ -751,7 +761,7 @@ class CreateEngineTest(oslo_test.BaseTestCase):
def warn_interpolate(msg, args):
# test the interpolation itself to ensure the password
# is concealed
- warnings.warning(msg % args)
+ warnings.warning(msg % (args, ))
with mock.patch(
"oslo_db.sqlalchemy.engines.LOG.warning",