db: Don't pass strings to 'Connection.execute'

Resolve the following RemovedIn20Warning warning:

  Passing a string to Connection.execute() is deprecated and will be
  removed in version 2.0.  Use the text() construct, or the
  Connection.exec_driver_sql() method to invoke a driver-level SQL
  string.

Change-Id: I44d6bf1ebfaf24f00a21389364456bceaae7c4d1
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
Stephen Finucane 2021-08-20 12:49:43 +01:00 committed by Stephen Finucane
parent 5d2399e210
commit b88ea30701
6 changed files with 83 additions and 58 deletions

View File

@ -1574,19 +1574,25 @@ def upgrade(migrate_engine):
if migrate_engine.name == 'mysql': if migrate_engine.name == 'mysql':
# In Folsom we explicitly converted migrate_version to UTF8. # In Folsom we explicitly converted migrate_version to UTF8.
migrate_engine.execute( with migrate_engine.connect() as conn:
'ALTER TABLE migrate_version CONVERT TO CHARACTER SET utf8') conn.exec_driver_sql(
# Set default DB charset to UTF8. 'ALTER TABLE migrate_version CONVERT TO CHARACTER SET utf8'
migrate_engine.execute( )
'ALTER DATABASE `%s` DEFAULT CHARACTER SET utf8' % # Set default DB charset to UTF8.
migrate_engine.url.database) conn.exec_driver_sql(
'ALTER DATABASE `%s` DEFAULT CHARACTER SET utf8' % (
migrate_engine.url.database,
)
)
# NOTE(cdent): The resource_providers table is defined as latin1 to be # NOTE(cdent): The resource_providers table is defined as latin1 to
# more efficient. Now we need the name column to be UTF8. We modify it # be more efficient. Now we need the name column to be UTF8. We
# here otherwise the declarative handling in sqlalchemy gets confused. # modify it here otherwise the declarative handling in sqlalchemy
migrate_engine.execute( # gets confused.
'ALTER TABLE resource_providers MODIFY name ' conn.exec_driver_sql(
'VARCHAR(200) CHARACTER SET utf8') 'ALTER TABLE resource_providers MODIFY name '
'VARCHAR(200) CHARACTER SET utf8'
)
_create_shadow_tables(migrate_engine) _create_shadow_tables(migrate_engine)
@ -1596,9 +1602,10 @@ def upgrade(migrate_engine):
# also # also
if migrate_engine.name == 'mysql': if migrate_engine.name == 'mysql':
# Use binary collation for extra specs table with migrate_engine.connect() as conn:
migrate_engine.execute( # Use binary collation for extra specs table
'ALTER TABLE instance_type_extra_specs ' conn.exec_driver_sql(
'CONVERT TO CHARACTER SET utf8 ' 'ALTER TABLE instance_type_extra_specs '
'COLLATE utf8_bin' 'CONVERT TO CHARACTER SET utf8 '
) 'COLLATE utf8_bin'
)

View File

@ -388,7 +388,7 @@ class TestCase(base.BaseTestCase):
engine = db_api.get_engine() engine = db_api.get_engine()
dialect = engine.url.get_dialect() dialect = engine.url.get_dialect()
if dialect == sqlite.dialect: if dialect == sqlite.dialect:
engine.connect().execute("PRAGMA foreign_keys = ON") engine.connect().exec_driver_sql("PRAGMA foreign_keys = ON")
def start_service(self, name, host=None, cell_name=None, **kwargs): def start_service(self, name, host=None, cell_name=None, **kwargs):
# Disallow starting multiple scheduler services # Disallow starting multiple scheduler services

View File

@ -889,12 +889,6 @@ class WarningsFixture(fixtures.Fixture):
message=r'The Connection.connect\(\) method is considered .*', message=r'The Connection.connect\(\) method is considered .*',
category=sqla_exc.SADeprecationWarning) category=sqla_exc.SADeprecationWarning)
warnings.filterwarnings(
'ignore',
module='nova',
message=r'Passing a string to Connection.execute\(\) is .*',
category=sqla_exc.SADeprecationWarning)
warnings.filterwarnings( warnings.filterwarnings(
'ignore', 'ignore',
module='nova', module='nova',

View File

@ -5688,7 +5688,9 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin):
metadata.reflect() metadata.reflect()
for table in metadata.tables: for table in metadata.tables:
if table.startswith("shadow_") and table not in exceptions: if table.startswith("shadow_") and table not in exceptions:
rows = self.conn.execute("select * from %s" % table).fetchall() rows = self.conn.exec_driver_sql(
"SELECT * FROM %s" % table
).fetchall()
self.assertEqual(rows, [], "Table %s not empty" % table) self.assertEqual(rows, [], "Table %s not empty" % table)
def test_shadow_tables(self): def test_shadow_tables(self):

View File

@ -37,6 +37,8 @@ from oslo_db.sqlalchemy import utils as oslodbutils
from oslo_log.fixture import logging_error as log_fixture from oslo_log.fixture import logging_error as log_fixture
from oslo_log import log as logging from oslo_log import log as logging
from oslotest import base from oslotest import base
import sqlalchemy as sa
import sqlalchemy.exc
from nova.db.main import models from nova.db.main import models
from nova.db import migration from nova.db import migration
@ -137,21 +139,29 @@ class TestModelsSyncMySQL(
def test_innodb_tables(self): def test_innodb_tables(self):
self.db_sync(self.get_engine()) self.db_sync(self.get_engine())
total = self.engine.execute( with self.engine.connect() as conn:
"SELECT count(*) " total = conn.execute(
"FROM information_schema.TABLES " sa.text(
"WHERE TABLE_SCHEMA = '%(database)s'" % "SELECT count(*) "
{'database': self.engine.url.database}) "FROM information_schema.TABLES "
"WHERE TABLE_SCHEMA = :database"
),
{'database': self.engine.url.database},
)
self.assertGreater(total.scalar(), 0, "No tables found. Wrong schema?") self.assertGreater(total.scalar(), 0, "No tables found. Wrong schema?")
noninnodb = self.engine.execute( with self.engine.connect() as conn:
"SELECT count(*) " noninnodb = conn.execute(
"FROM information_schema.TABLES " sa.text(
"WHERE TABLE_SCHEMA='%(database)s' " "SELECT count(*) "
"AND ENGINE != 'InnoDB' " "FROM information_schema.TABLES "
"AND TABLE_NAME != 'migrate_version'" % "WHERE TABLE_SCHEMA = :database "
{'database': self.engine.url.database}) "AND ENGINE != 'InnoDB' "
count = noninnodb.scalar() "AND TABLE_NAME != 'migrate_version'"
),
{'database': self.engine.url.database},
)
count = noninnodb.scalar()
self.assertEqual(count, 0, "%d non InnoDB tables created" % count) self.assertEqual(count, 0, "%d non InnoDB tables created" % count)

View File

@ -28,7 +28,7 @@ from oslo_utils.fixture import uuidsentinel as uuids
from oslo_utils import timeutils from oslo_utils import timeutils
from oslo_utils import uuidutils from oslo_utils import uuidutils
from oslotest import output from oslotest import output
import sqlalchemy import sqlalchemy as sa
import testtools import testtools
from nova.compute import rpcapi as compute_rpcapi from nova.compute import rpcapi as compute_rpcapi
@ -125,17 +125,19 @@ class TestDatabaseFixture(testtools.TestCase):
self.useFixture(db_fixture) self.useFixture(db_fixture)
engine = main_db_api.get_engine() engine = main_db_api.get_engine()
conn = engine.connect() conn = engine.connect()
result = conn.execute("select * from instance_types") result = conn.execute(sa.text("SELECT * FROM instance_types"))
rows = result.fetchall() rows = result.fetchall()
self.assertEqual(0, len(rows), "Rows %s" % rows) self.assertEqual(0, len(rows), "Rows %s" % rows)
# insert a 6th instance type, column 5 below is an int id # insert a 6th instance type, column 5 below is an int id
# which has a constraint on it, so if new standard instance # which has a constraint on it, so if new standard instance
# types are added you have to bump it. # types are added you have to bump it.
conn.execute("insert into instance_types VALUES " conn.execute(sa.text(
"(NULL, NULL, NULL, 't1.test', 6, 4096, 2, 0, NULL, '87'" "INSERT INTO instance_types VALUES "
", 1.0, 40, 0, 0, 1, 0)") "(NULL, NULL, NULL, 't1.test', 6, 4096, 2, 0, NULL, '87'"
result = conn.execute("select * from instance_types") ", 1.0, 40, 0, 0, 1, 0)"
))
result = conn.execute(sa.text("SELECT * FROM instance_types"))
rows = result.fetchall() rows = result.fetchall()
self.assertEqual(1, len(rows), "Rows %s" % rows) self.assertEqual(1, len(rows), "Rows %s" % rows)
@ -145,7 +147,7 @@ class TestDatabaseFixture(testtools.TestCase):
db_fixture.reset() db_fixture.reset()
engine = main_db_api.get_engine() engine = main_db_api.get_engine()
conn = engine.connect() conn = engine.connect()
result = conn.execute("select * from instance_types") result = conn.execute(sa.text("SELECT * FROM instance_types"))
rows = result.fetchall() rows = result.fetchall()
self.assertEqual(0, len(rows), "Rows %s" % rows) self.assertEqual(0, len(rows), "Rows %s" % rows)
@ -156,14 +158,19 @@ class TestDatabaseFixture(testtools.TestCase):
self.useFixture(db_fixture) self.useFixture(db_fixture)
engine = api_db_api.get_engine() engine = api_db_api.get_engine()
conn = engine.connect() conn = engine.connect()
result = conn.execute("select * from cell_mappings") result = conn.execute(sa.text("SELECT * FROM cell_mappings"))
rows = result.fetchall() rows = result.fetchall()
self.assertEqual(0, len(rows), "Rows %s" % rows) self.assertEqual(0, len(rows), "Rows %s" % rows)
uuid = uuidutils.generate_uuid() uuid = uuidutils.generate_uuid()
conn.execute("insert into cell_mappings (uuid, name) VALUES " conn.execute(
"('%s', 'fake-cell')" % (uuid,)) sa.text(
result = conn.execute("select * from cell_mappings") "INSERT INTO cell_mappings (uuid, name) VALUES (:uuid, :name)"
),
uuid=uuid,
name='fake-cell',
)
result = conn.execute(sa.text("SELECT * FROM cell_mappings"))
rows = result.fetchall() rows = result.fetchall()
self.assertEqual(1, len(rows), "Rows %s" % rows) self.assertEqual(1, len(rows), "Rows %s" % rows)
@ -173,7 +180,7 @@ class TestDatabaseFixture(testtools.TestCase):
db_fixture.reset() db_fixture.reset()
engine = api_db_api.get_engine() engine = api_db_api.get_engine()
conn = engine.connect() conn = engine.connect()
result = conn.execute("select * from cell_mappings") result = conn.execute(sa.text("SELECT * FROM cell_mappings"))
rows = result.fetchall() rows = result.fetchall()
self.assertEqual(0, len(rows), "Rows %s" % rows) self.assertEqual(0, len(rows), "Rows %s" % rows)
@ -202,9 +209,14 @@ class TestDatabaseFixture(testtools.TestCase):
engine = api_db_api.get_engine() engine = api_db_api.get_engine()
conn = engine.connect() conn = engine.connect()
uuid = uuidutils.generate_uuid() uuid = uuidutils.generate_uuid()
conn.execute("insert into cell_mappings (uuid, name) VALUES " conn.execute(
"('%s', 'fake-cell')" % (uuid,)) sa.text(
result = conn.execute("select * from cell_mappings") "INSERT INTO cell_mappings (uuid, name) VALUES (:uuid, :name)"
),
uuid=uuid,
name='fake-cell',
)
result = conn.execute(sa.text("SELECT * FROM cell_mappings"))
rows = result.fetchall() rows = result.fetchall()
self.assertEqual(1, len(rows), "Rows %s" % rows) self.assertEqual(1, len(rows), "Rows %s" % rows)
@ -227,13 +239,13 @@ class TestDefaultFlavorsFixture(testtools.TestCase):
engine = api_db_api.get_engine() engine = api_db_api.get_engine()
conn = engine.connect() conn = engine.connect()
result = conn.execute("select * from flavors") result = conn.execute(sa.text("SELECT * FROM flavors"))
rows = result.fetchall() rows = result.fetchall()
self.assertEqual(0, len(rows), "Rows %s" % rows) self.assertEqual(0, len(rows), "Rows %s" % rows)
self.useFixture(fixtures.DefaultFlavorsFixture()) self.useFixture(fixtures.DefaultFlavorsFixture())
result = conn.execute("select * from flavors") result = conn.execute(sa.text("SELECT * FROM flavors"))
rows = result.fetchall() rows = result.fetchall()
self.assertEqual(6, len(rows), "Rows %s" % rows) self.assertEqual(6, len(rows), "Rows %s" % rows)
@ -323,7 +335,7 @@ class TestSynchronousThreadPoolExecutorFixture(testtools.TestCase):
class TestBannedDBSchemaOperations(testtools.TestCase): class TestBannedDBSchemaOperations(testtools.TestCase):
def test_column(self): def test_column(self):
column = sqlalchemy.Column() column = sa.Column()
with fixtures.BannedDBSchemaOperations(['Column']): with fixtures.BannedDBSchemaOperations(['Column']):
self.assertRaises(exception.DBNotAllowed, self.assertRaises(exception.DBNotAllowed,
column.drop) column.drop)
@ -331,7 +343,7 @@ class TestBannedDBSchemaOperations(testtools.TestCase):
column.alter) column.alter)
def test_table(self): def test_table(self):
table = sqlalchemy.Table() table = sa.Table()
with fixtures.BannedDBSchemaOperations(['Table']): with fixtures.BannedDBSchemaOperations(['Table']):
self.assertRaises(exception.DBNotAllowed, self.assertRaises(exception.DBNotAllowed,
table.drop) table.drop)