diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-09-06 17:56:10 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-09-07 09:31:43 -0400 |
commit | b19738a13a08f9ff5ac2357060250d121c680163 (patch) | |
tree | 8f62b21b20b176e6b3aaf4182508b17f937fa53c | |
parent | d6cbc36f63ccb60beffa6bc9c3ebdf9a0b5a12c3 (diff) | |
download | oslo-db-b19738a13a08f9ff5ac2357060250d121c680163.tar.gz |
Add additional caution looking for table, info
A joined inheritance mapper is mapped to a join();
these have no .info attribute, so use that
of the local table instead. The sorting order when
querying against a joined subclass table
can at least be derived from the base table, so
use the base mapper's table. It may be a better idea
to comprise the constraints amongst the base table
*and* the joined table, though.
Change-Id: I9466c9dbbbdc4af10ab0f15ee0f558199973c1ec
-rw-r--r-- | oslo_db/sqlalchemy/utils.py | 21 | ||||
-rw-r--r-- | oslo_db/tests/sqlalchemy/test_utils.py | 25 |
2 files changed, 37 insertions, 9 deletions
diff --git a/oslo_db/sqlalchemy/utils.py b/oslo_db/sqlalchemy/utils.py index f5dda31..87c6f07 100644 --- a/oslo_db/sqlalchemy/utils.py +++ b/oslo_db/sqlalchemy/utils.py @@ -80,18 +80,22 @@ def get_unique_keys(model): except exc.NoInspectionAvailable: return None else: - table = mapper.mapped_table - if table is None: + local_table = mapper.local_table + base_table = mapper.base_mapper.local_table + + if local_table is None: return None # extract result from cache if present - info = table.info - if 'oslodb_unique_keys' in info: - return info['oslodb_unique_keys'] + has_info = hasattr(local_table, 'info') + if has_info: + info = local_table.info + if 'oslodb_unique_keys' in info: + return info['oslodb_unique_keys'] res = [] try: - constraints = table.constraints + constraints = base_table.constraints except AttributeError: constraints = [] for constraint in constraints: @@ -100,14 +104,15 @@ def get_unique_keys(model): sqlalchemy.PrimaryKeyConstraint)): res.append({c.name for c in constraint.columns}) try: - indexes = table.indexes + indexes = base_table.indexes except AttributeError: indexes = [] for index in indexes: if index.unique: res.append({c.name for c in index.columns}) # cache result for next calls with the same model - info['oslodb_unique_keys'] = res + if has_info: + info['oslodb_unique_keys'] = res return res diff --git a/oslo_db/tests/sqlalchemy/test_utils.py b/oslo_db/tests/sqlalchemy/test_utils.py index e5f5a6c..1471ff1 100644 --- a/oslo_db/tests/sqlalchemy/test_utils.py +++ b/oslo_db/tests/sqlalchemy/test_utils.py @@ -94,6 +94,16 @@ class FakeTable(Base): pass +class FakeTableJoinedInh(FakeTable): + __tablename__ = 'fake_table_inh' + + id = Column(String(50), ForeignKey('fake_table.user_id')) + + +class FakeTableSingleInh(FakeTable): + __mapper_args__ = {'polymorphic_identity': 'foo'} + + class FakeTableWithMultipleKeys(Base): __tablename__ = 'fake_table_multiple_keys' @@ -328,6 +338,16 @@ class Test_UnstableSortingOrder(test_base.BaseTestCase): utils._stable_sorting_order( FakeTableWithMultipleKeys, ['key1', 'key3'])) + def test_joined_inh_stable(self): + self.assertTrue( + utils._stable_sorting_order(FakeTableJoinedInh, ['user_id']) + ) + + def test_single_inh_stable(self): + self.assertTrue( + utils._stable_sorting_order(FakeTableSingleInh, ['user_id']) + ) + def test_unknown_primary_keys_stable(self): self.assertIsNone( utils._stable_sorting_order(object, ['key1', 'key2'])) @@ -378,7 +398,10 @@ class TestGetUniqueKeys(test_base.BaseTestCase): pass table = CacheTable() - mock_inspect = mock.Mock(return_value=mock.Mock(mapped_table=table)) + mapper_mock = mock.Mock(mapped_table=table, local_table=table) + mapper_mock.base_mapper = mapper_mock + mock_inspect = mock.Mock( + return_value=mapper_mock) model = CacheModel() self.assertNotIn('oslodb_unique_keys', CacheTable.info) with mock.patch("oslo_db.sqlalchemy.utils.inspect", mock_inspect): |