summaryrefslogtreecommitdiff
path: root/oslo_db/sqlalchemy
diff options
context:
space:
mode:
authorJulien Danjou <julien@danjou.info>2016-09-02 10:40:16 +0200
committerJulien Danjou <julien@danjou.info>2016-09-03 10:29:42 +0200
commitbf3b21f75b94a4d8b533dd10fdeb9a64da344cf9 (patch)
tree5176ddff539573f1d89a8fffed04f8e0e88c47f3 /oslo_db/sqlalchemy
parent2aec826a51562c6b6bdccd3a7d27f62e107ae150 (diff)
downloadoslo-db-bf3b21f75b94a4d8b533dd10fdeb9a64da344cf9.tar.gz
utils: fix get_unique_keys() when model has no table attached to it4.13.2
Using the internal SQLAlchemy __table__ to find unique keys on a model class does not work if the model is not attached to a class. In this case, it seems there is no way to find what the keys are: rather than crashing or returning garbage, the function just returns None, indicating it does not know how to get it. The warning from paginate_query() is not emitted in this case, as there's no way to guess if the developer did wrong or not. Change-Id: I1291fe1f1e78471f18f230a66edff31ed199bc7a (cherry picked from commit 49eaed489e4650e56ed2e270ba3e15ce2b421cc8)
Diffstat (limited to 'oslo_db/sqlalchemy')
-rw-r--r--oslo_db/sqlalchemy/utils.py31
1 files changed, 25 insertions, 6 deletions
diff --git a/oslo_db/sqlalchemy/utils.py b/oslo_db/sqlalchemy/utils.py
index 136e05a..016bae7 100644
--- a/oslo_db/sqlalchemy/utils.py
+++ b/oslo_db/sqlalchemy/utils.py
@@ -31,6 +31,7 @@ from sqlalchemy import Column
from sqlalchemy.engine import Connectable
from sqlalchemy.engine import reflection
from sqlalchemy.engine import url as sa_url
+from sqlalchemy import exc
from sqlalchemy import func
from sqlalchemy import Index
from sqlalchemy import inspect
@@ -71,16 +72,26 @@ def _get_unique_keys(model):
:param model: the ORM model class
:rtype: list of sets of strings
- :return: unique model keys
+ :return: unique model keys or None if unable to find them
"""
+
+ try:
+ mapper = inspect(model)
+ except exc.NoInspectionAvailable:
+ return None
+ else:
+ table = mapper.mapped_table
+ if table is None:
+ return None
+
# extract result from cache if present
- info = model.__table__.info
+ info = table.info
if 'oslodb_unique_keys' in info:
return info['oslodb_unique_keys']
res = []
try:
- constraints = model.__table__.constraints
+ constraints = table.constraints
except AttributeError:
constraints = []
for constraint in constraints:
@@ -89,7 +100,7 @@ def _get_unique_keys(model):
sqlalchemy.PrimaryKeyConstraint)):
res.append({c.name for c in constraint.columns})
try:
- indexes = model.__table__.indexes
+ indexes = table.indexes
except AttributeError:
indexes = []
for index in indexes:
@@ -101,8 +112,16 @@ def _get_unique_keys(model):
def _stable_sorting_order(model, sort_keys):
+ """Check whetever the sorting order is stable.
+
+ :return: True if it is stable, False if it's not, None if it's impossible
+ to determine.
+ """
+ keys = _get_unique_keys(model)
+ if keys is None:
+ return None
sort_keys_set = set(sort_keys)
- for unique_keys in _get_unique_keys(model):
+ for unique_keys in keys:
if unique_keys.issubset(sort_keys_set):
return True
return False
@@ -142,7 +161,7 @@ def paginate_query(query, model, limit, sort_keys, marker=None,
:rtype: sqlalchemy.orm.query.Query
:return: The query with sorting/pagination added.
"""
- if not _stable_sorting_order(model, sort_keys):
+ if _stable_sorting_order(model, sort_keys) is False:
LOG.warning(_LW('Unique keys not in sort_keys. '
'The sorting order may be unstable.'))