Replace "Inspector.from_engine()" with "sqlalchemy.inspect()"

Since SQLAlchemy 1.4, the method "Inspector.from_engine()" is
deprecated.

Error message:
"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. (deprecated
since: 1.4)"

Minimum version of SQLAlchemy required is bumped to 1.4.23.

Change-Id: I6cf5944ccb3a0532cbf123ddc0d7df6b6de80af1
Closes-Bug: #1943155
This commit is contained in:
Rodolfo Alonso Hernandez 2021-09-09 15:14:06 +00:00
parent d25cfaa702
commit 42fda206e9
16 changed files with 24 additions and 34 deletions

View File

@ -117,7 +117,7 @@ simplejson==3.5.1
smmap==0.9.0 smmap==0.9.0
snowballstemmer==1.2.1 snowballstemmer==1.2.1
sqlalchemy-migrate==0.11.0 sqlalchemy-migrate==0.11.0
SQLAlchemy==1.3.23 SQLAlchemy==1.4.23
sqlparse==0.2.2 sqlparse==0.2.2
statsd==3.2.1 statsd==3.2.1
stestr==1.0.0 stestr==1.0.0

View File

@ -18,7 +18,6 @@ import functools
from alembic import context from alembic import context
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.engine import reflection
from neutron._i18n import _ from neutron._i18n import _
@ -84,8 +83,7 @@ def schema_has_table(table_name):
This method cannot be executed in offline mode. This method cannot be executed in offline mode.
""" """
bind = op.get_bind() insp = sa.inspect(op.get_bind())
insp = sa.engine.reflection.Inspector.from_engine(bind)
return table_name in insp.get_table_names() return table_name in insp.get_table_names()
@ -95,8 +93,7 @@ def schema_has_column(table_name, column_name):
This method cannot be executed in offline mode. This method cannot be executed in offline mode.
""" """
bind = op.get_bind() insp = sa.inspect(op.get_bind())
insp = sa.engine.reflection.Inspector.from_engine(bind)
# first check that the table exists # first check that the table exists
if not schema_has_table(table_name): if not schema_has_table(table_name):
return return
@ -218,7 +215,7 @@ def create_table_if_not_exist_psql(table_name, values):
def get_unique_constraints_map(table): def get_unique_constraints_map(table):
inspector = reflection.Inspector.from_engine(op.get_bind()) inspector = sa.inspect(op.get_bind())
return { return {
tuple(sorted(cons['column_names'])): cons['name'] tuple(sorted(cons['column_names'])): cons['name']
for cons in inspector.get_unique_constraints(table) for cons in inspector.get_unique_constraints(table)
@ -262,7 +259,7 @@ def create_foreign_keys(table, foreign_keys):
@contextlib.contextmanager @contextlib.contextmanager
def remove_fks_from_table(table, remove_unique_constraints=False): def remove_fks_from_table(table, remove_unique_constraints=False):
try: try:
inspector = reflection.Inspector.from_engine(op.get_bind()) inspector = sa.inspect(op.get_bind())
foreign_keys = inspector.get_foreign_keys(table) foreign_keys = inspector.get_foreign_keys(table)
remove_foreign_keys(table, foreign_keys) remove_foreign_keys(table, foreign_keys)
if remove_unique_constraints: if remove_unique_constraints:
@ -273,7 +270,7 @@ def remove_fks_from_table(table, remove_unique_constraints=False):
def pk_on_alembic_version_table(): def pk_on_alembic_version_table():
inspector = reflection.Inspector.from_engine(op.get_bind()) inspector = sa.inspect(op.get_bind())
pk = inspector.get_pk_constraint('alembic_version') pk = inspector.get_pk_constraint('alembic_version')
if not pk['constrained_columns']: if not pk['constrained_columns']:
op.create_primary_key(op.f('pk_alembic_version'), op.create_primary_key(op.f('pk_alembic_version'),

View File

@ -14,7 +14,7 @@
# #
from alembic import op from alembic import op
from sqlalchemy.engine import reflection import sqlalchemy
from neutron.db import migration from neutron.db import migration
@ -35,7 +35,7 @@ TABLE_NAME = 'flavorserviceprofilebindings'
def upgrade(): def upgrade():
inspector = reflection.Inspector.from_engine(op.get_bind()) inspector = sqlalchemy.inspect(op.get_bind())
fk_constraints = inspector.get_foreign_keys(TABLE_NAME) fk_constraints = inspector.get_foreign_keys(TABLE_NAME)
for fk in fk_constraints: for fk in fk_constraints:
fk['options']['ondelete'] = 'CASCADE' fk['options']['ondelete'] = 'CASCADE'

View File

@ -60,7 +60,7 @@ def check_sanity(connection):
def get_duplicate_l3_ha_port_bindings(connection): def get_duplicate_l3_ha_port_bindings(connection):
insp = sa.engine.reflection.Inspector.from_engine(connection) insp = sa.inspect(connection)
if 'ha_router_agent_port_bindings' not in insp.get_table_names(): if 'ha_router_agent_port_bindings' not in insp.get_table_names():
return {} return {}
session = sa.orm.Session(bind=connection.connect()) session = sa.orm.Session(bind=connection.connect())

View File

@ -41,8 +41,7 @@ def get_inspector():
return _INSPECTOR return _INSPECTOR
else: else:
bind = op.get_bind() _INSPECTOR = sa.inspect(op.get_bind())
_INSPECTOR = sa.engine.reflection.Inspector.from_engine(bind)
return _INSPECTOR return _INSPECTOR

View File

@ -11,7 +11,7 @@
# under the License. # under the License.
from alembic import op from alembic import op
from sqlalchemy.engine import reflection import sqlalchemy
"""Rename ml2_network_segments table """Rename ml2_network_segments table
@ -45,7 +45,7 @@ def upgrade():
def delete_foreign_key_constraint(): def delete_foreign_key_constraint():
inspector = reflection.Inspector.from_engine(op.get_bind()) inspector = sqlalchemy.inspect(op.get_bind())
fk_constraints = inspector.get_foreign_keys(TABLE_NAME) fk_constraints = inspector.get_foreign_keys(TABLE_NAME)
for fk in fk_constraints: for fk in fk_constraints:
if fk['referred_table'] == OLD_REFERRED_TABLE_NAME: if fk['referred_table'] == OLD_REFERRED_TABLE_NAME:

View File

@ -58,7 +58,7 @@ def check_sanity(connection):
def get_duplicate_port_records_in_routerport_database(connection): def get_duplicate_port_records_in_routerport_database(connection):
insp = sa.engine.reflection.Inspector.from_engine(connection) insp = sa.inspect(connection)
if 'routerports' not in insp.get_table_names(): if 'routerports' not in insp.get_table_names():
return [] return []
session = sa.orm.Session(bind=connection.connect()) session = sa.orm.Session(bind=connection.connect())

View File

@ -60,7 +60,7 @@ def check_sanity(connection):
def get_duplicate_floating_ip_for_one_fixed_ip(connection): def get_duplicate_floating_ip_for_one_fixed_ip(connection):
insp = sa.engine.reflection.Inspector.from_engine(connection) insp = sa.inspect(connection)
if 'floatingips' not in insp.get_table_names(): if 'floatingips' not in insp.get_table_names():
return [] return []
session = sa.orm.Session(bind=connection.connect()) session = sa.orm.Session(bind=connection.connect())

View File

@ -16,7 +16,6 @@
from alembic import op from alembic import op
from neutron_lib import constants from neutron_lib import constants
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.engine.reflection import Inspector as insp
from neutron.db import migration from neutron.db import migration
@ -51,7 +50,7 @@ def upgrade():
op.execute("ALTER TABLE ml2_port_bindings DROP PRIMARY KEY," op.execute("ALTER TABLE ml2_port_bindings DROP PRIMARY KEY,"
"ADD PRIMARY KEY(port_id, host);") "ADD PRIMARY KEY(port_id, host);")
else: else:
inspector = insp.from_engine(bind) inspector = sa.inspect(bind)
pk_constraint = inspector.get_pk_constraint(ML2_PORT_BINDING) pk_constraint = inspector.get_pk_constraint(ML2_PORT_BINDING)
op.drop_constraint(pk_constraint.get('name'), ML2_PORT_BINDING, op.drop_constraint(pk_constraint.get('name'), ML2_PORT_BINDING,
type_='primary') type_='primary')

View File

@ -23,7 +23,6 @@ Create Date: 2018-10-12 19:51:11.981394
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.engine import reflection
from neutron.db import migration from neutron.db import migration
@ -35,7 +34,7 @@ TABLE_NAME = 'portforwardings'
def upgrade(): def upgrade():
inspector = reflection.Inspector.from_engine(op.get_bind()) inspector = sa.inspect(op.get_bind())
foreign_keys = inspector.get_foreign_keys(TABLE_NAME) foreign_keys = inspector.get_foreign_keys(TABLE_NAME)
migration.remove_foreign_keys(TABLE_NAME, foreign_keys) migration.remove_foreign_keys(TABLE_NAME, foreign_keys)

View File

@ -15,7 +15,6 @@
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.engine import reflection
from neutron.db import migration from neutron.db import migration
@ -40,7 +39,7 @@ COLUMN_IN_USE = 'in_use'
def upgrade(): def upgrade():
inspector = reflection.Inspector.from_engine(op.get_bind()) inspector = sa.inspect(op.get_bind())
# NOTE(ralonsoh): bug #1865891 is present in stable releases. Although is # NOTE(ralonsoh): bug #1865891 is present in stable releases. Although is
# not possible to backport a patch implementing a DB change [1], we are # not possible to backport a patch implementing a DB change [1], we are
# planning to migrate this patch to a stable branch in a private # planning to migrate this patch to a stable branch in a private

View File

@ -15,7 +15,6 @@
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from sqlalchemy.engine import reflection
"""ovn backend """ovn backend
@ -35,7 +34,7 @@ OVN_HASH_RING = 'ovn_hash_ring'
def upgrade(): def upgrade():
inspector = reflection.Inspector.from_engine(op.get_bind()) inspector = sa.inspect(op.get_bind())
table_names = inspector.get_table_names() table_names = inspector.get_table_names()
if OVN_REVISION_NUMBERS in table_names and OVN_HASH_RING in table_names: if OVN_REVISION_NUMBERS in table_names and OVN_HASH_RING in table_names:
op.alter_column(OVN_REVISION_NUMBERS, 'revision_number', op.alter_column(OVN_REVISION_NUMBERS, 'revision_number',

View File

@ -47,7 +47,7 @@ class DuplicateQuotas(exceptions.Conflict):
def get_duplicate_quotas(connection): def get_duplicate_quotas(connection):
insp = sa.engine.reflection.Inspector.from_engine(connection) insp = sa.inspect(connection)
if 'quotas' not in insp.get_table_names(): if 'quotas' not in insp.get_table_names():
return [] return []
session = sa.orm.Session(bind=connection.connect()) session = sa.orm.Session(bind=connection.connect())

View File

@ -175,8 +175,7 @@ class _TestModelsMigrations(test_migrations.ModelsMigrationsSync):
# Remove some difference that are not mistakes just specific of # Remove some difference that are not mistakes just specific of
# dialects, etc # dialects, etc
def remove_unrelated_errors(self, element): def remove_unrelated_errors(self, element):
insp = sqlalchemy.engine.reflection.Inspector.from_engine( insp = sqlalchemy.inspect(self.get_engine())
self.get_engine())
dialect = self.get_engine().dialect.name dialect = self.get_engine().dialect.name
if isinstance(element, tuple): if isinstance(element, tuple):
if dialect == 'mysql' and element[0] == 'remove_index': if dialect == 'mysql' and element[0] == 'remove_index':
@ -351,7 +350,7 @@ class TestModelsMigrationsMysql(testlib_api.MySQLTestCaseMixin,
self.alembic_config.attributes['connection'] = connection self.alembic_config.attributes['connection'] = connection
migration.do_alembic_command(self.alembic_config, 'upgrade', migration.do_alembic_command(self.alembic_config, 'upgrade',
'heads') 'heads')
insp = sqlalchemy.engine.reflection.Inspector.from_engine(engine) insp = sqlalchemy.inspect(engine)
# Test that table creation on MySQL only builds InnoDB tables # Test that table creation on MySQL only builds InnoDB tables
tables = insp.get_table_names() tables = insp.get_table_names()
self.assertGreater(len(tables), 0, self.assertGreater(len(tables), 0,

View File

@ -81,15 +81,14 @@ class TestDbMigration(base.BaseTestCase):
self.mock_alembic_is_offline = mock.patch( self.mock_alembic_is_offline = mock.patch(
'alembic.context.is_offline_mode', return_value=False).start() 'alembic.context.is_offline_mode', return_value=False).start()
self.mock_alembic_is_offline.return_value = False self.mock_alembic_is_offline.return_value = False
self.mock_sa_inspector = mock.patch( self.mock_sa_inspector = mock.patch('sqlalchemy.inspect').start()
'sqlalchemy.engine.reflection.Inspector').start()
def _prepare_mocked_sqlalchemy_inspector(self): def _prepare_mocked_sqlalchemy_inspector(self):
mock_inspector = mock.MagicMock() mock_inspector = mock.MagicMock()
mock_inspector.get_table_names.return_value = ['foo', 'bar'] mock_inspector.get_table_names.return_value = ['foo', 'bar']
mock_inspector.get_columns.return_value = [{'name': 'foo_column'}, mock_inspector.get_columns.return_value = [{'name': 'foo_column'},
{'name': 'bar_column'}] {'name': 'bar_column'}]
self.mock_sa_inspector.from_engine.return_value = mock_inspector self.mock_sa_inspector.return_value = mock_inspector
def test_schema_has_table(self): def test_schema_has_table(self):
self._prepare_mocked_sqlalchemy_inspector() self._prepare_mocked_sqlalchemy_inspector()

View File

@ -19,7 +19,7 @@ netifaces>=0.10.4 # MIT
neutron-lib>=2.15.0 # Apache-2.0 neutron-lib>=2.15.0 # Apache-2.0
python-neutronclient>=6.7.0 # Apache-2.0 python-neutronclient>=6.7.0 # Apache-2.0
tenacity>=6.0.0 # Apache-2.0 tenacity>=6.0.0 # Apache-2.0
SQLAlchemy>=1.3.23 # MIT SQLAlchemy>=1.4.23 # MIT
WebOb>=1.8.2 # MIT WebOb>=1.8.2 # MIT
keystoneauth1>=3.14.0 # Apache-2.0 keystoneauth1>=3.14.0 # Apache-2.0
alembic>=1.6.5 # MIT alembic>=1.6.5 # MIT