tests: Enable SADeprecationWarning warnings
Highlight use of deprecated SQLAlchemy APIs to ensure we keep on top of things. This requires resolving the following SADeprecationWarning warnings: The from_engine() method on Inspector is deprecated and will be removed in a future release. Please use the sqlalchemy.inspect() function on an Engine or Connection in order to acquire an Inspector. The Column.copy() method is deprecated and will be removed in a future release. The ColumnCollectionConstraint.copy() method is deprecated and will be removed in a future release. There are more warnings to be resolved related to SQLAlchemy 2.0, but those require a special environment option (SQLALCHEMY_WARN_20) to trigger and a lot of work to resolve. We'll address those in a series of follow-ups. Change-Id: I34b395e6d50f4e4151178c327d94308e6f5d5b6e Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
parent
a6007a98b1
commit
40bce5a2ba
@ -31,7 +31,6 @@ from sqlalchemy import Boolean
|
||||
from sqlalchemy import CheckConstraint
|
||||
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
|
||||
@ -578,12 +577,16 @@ def _change_deleted_column_type_to_boolean_sqlite(engine, table_name,
|
||||
column_copy = _get_not_supported_column(col_name_col_instance,
|
||||
column.name)
|
||||
else:
|
||||
column_copy = column.copy()
|
||||
# FIXME(stephenfin): We shouldn't be using this private API;
|
||||
# figure out how else to copy an arbitrary column schema
|
||||
column_copy = column._copy()
|
||||
else:
|
||||
column_copy = Column('deleted', Boolean, default=0)
|
||||
columns.append(column_copy)
|
||||
|
||||
constraints = [constraint.copy() for constraint in table.constraints]
|
||||
# FIXME(stephenfin): We shouldn't be using this private API;
|
||||
# figure out how else to copy an arbitrary column schema
|
||||
constraints = [constraint._copy() for constraint in table.constraints]
|
||||
|
||||
meta = table.metadata
|
||||
new_table = Table(table_name + "__tmp__", meta,
|
||||
@ -652,12 +655,12 @@ def _is_deleted_column_constraint(constraint):
|
||||
|
||||
def _change_deleted_column_type_to_id_type_sqlite(engine, table_name,
|
||||
**col_name_col_instance):
|
||||
# NOTE(boris-42): sqlaclhemy-migrate can't drop column with check
|
||||
# constraints in sqlite DB and our `deleted` column has
|
||||
# 2 check constraints. So there is only one way to remove
|
||||
# these constraints:
|
||||
# 1) Create new table with the same columns, constraints
|
||||
# and indexes. (except deleted column).
|
||||
# NOTE(boris-42): sqlalchemy-migrate can't drop column with check
|
||||
# constraints in sqlite DB and our `deleted` column has two check
|
||||
# constraints. There is only one way to remove these constraints:
|
||||
#
|
||||
# 1) Create new table with the same columns, constraints and indexes.
|
||||
# (except deleted column).
|
||||
# 2) Copy all data from old to new table.
|
||||
# 3) Drop old table.
|
||||
# 4) Rename new table to old table name.
|
||||
@ -673,7 +676,9 @@ def _change_deleted_column_type_to_id_type_sqlite(engine, table_name,
|
||||
column_copy = _get_not_supported_column(col_name_col_instance,
|
||||
column.name)
|
||||
else:
|
||||
column_copy = column.copy()
|
||||
# FIXME(stephenfin): We shouldn't be using this private API;
|
||||
# figure out how else to copy an arbitrary column schema
|
||||
column_copy = column._copy()
|
||||
else:
|
||||
column_copy = Column('deleted', table.c.id.type,
|
||||
default=default_deleted_value)
|
||||
@ -682,7 +687,9 @@ def _change_deleted_column_type_to_id_type_sqlite(engine, table_name,
|
||||
constraints = []
|
||||
for constraint in table.constraints:
|
||||
if not _is_deleted_column_constraint(constraint):
|
||||
constraints.append(constraint.copy())
|
||||
# FIXME(stephenfin): We shouldn't be using this private API;
|
||||
# figure out how else to copy an arbitrary constraint schema
|
||||
constraints.append(constraint._copy())
|
||||
|
||||
new_table = Table(table_name + "__tmp__", meta,
|
||||
*(columns + constraints))
|
||||
@ -734,7 +741,7 @@ def get_indexes(engine, table_name):
|
||||
:param table_name: name of the table
|
||||
"""
|
||||
|
||||
inspector = reflection.Inspector.from_engine(engine)
|
||||
inspector = sqlalchemy.inspect(engine)
|
||||
indexes = inspector.get_indexes(table_name)
|
||||
return indexes
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
from oslotest import base
|
||||
|
||||
from oslo_db.tests import fixtures
|
||||
|
||||
|
||||
class BaseTestCase(base.BaseTestCase):
|
||||
"""Test case base class for all oslo.db unit tests."""
|
||||
@ -19,3 +21,5 @@ class BaseTestCase(base.BaseTestCase):
|
||||
def setUp(self):
|
||||
"""Run before each test method to initialize test environment."""
|
||||
super().setUp()
|
||||
|
||||
self.warning_fixture = self.useFixture(fixtures.WarningsFixture())
|
||||
|
36
oslo_db/tests/fixtures.py
Normal file
36
oslo_db/tests/fixtures.py
Normal file
@ -0,0 +1,36 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import warnings
|
||||
|
||||
import fixtures
|
||||
from sqlalchemy import exc as sqla_exc
|
||||
|
||||
|
||||
class WarningsFixture(fixtures.Fixture):
|
||||
"""Filters out warnings during test runs."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
# Make deprecation warnings only happen once to avoid spamming
|
||||
warnings.simplefilter('once', DeprecationWarning)
|
||||
|
||||
warnings.filterwarnings(
|
||||
'error', message='Evaluating non-mapped column expression',
|
||||
category=sqla_exc.SAWarning)
|
||||
|
||||
# Enable deprecation warnings to capture upcoming SQLAlchemy changes
|
||||
warnings.filterwarnings(
|
||||
'error',
|
||||
category=sqla_exc.SADeprecationWarning)
|
||||
|
||||
self.addCleanup(warnings.resetwarnings)
|
@ -24,7 +24,6 @@ from sqlalchemy import CheckConstraint
|
||||
from sqlalchemy import MetaData, Table, Column
|
||||
from sqlalchemy import ForeignKey, ForeignKeyConstraint
|
||||
from sqlalchemy.dialects.postgresql import psycopg2
|
||||
from sqlalchemy.engine import reflection
|
||||
from sqlalchemy.engine import url as sa_url
|
||||
from sqlalchemy.exc import OperationalError
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
@ -796,7 +795,7 @@ class TestMigrationUtils(db_test_base._DbTestCase):
|
||||
utils.change_deleted_column_type_to_id_type(self.engine, table_name)
|
||||
utils.change_deleted_column_type_to_boolean(self.engine, table_name)
|
||||
|
||||
insp = reflection.Inspector.from_engine(self.engine)
|
||||
insp = sqlalchemy.inspect(self.engine)
|
||||
real_indexes = insp.get_indexes(table_name)
|
||||
self.assertEqual(3, len(real_indexes))
|
||||
for index in real_indexes:
|
||||
|
Loading…
Reference in New Issue
Block a user