Introduce mysql_sql_mode option, remove old warning

Introduce a config option, mysql_sql_mode, that allows the user
to set the desired SQL mode for MySQL sessions.

For MySQL sessions, set the SQL mode session variable
accordingly.

For compatibility purposes, retain the mysql_traditional_mode
argument in method signatures, but only use it to override the
config option as if it were set to 'TRADITIONAL'.

Change-Id: Ia527e850671ab9542db5864617384cee21e91bf6
Closes-bug: 1271706
This commit is contained in:
Florian Haas 2014-01-22 20:52:36 +01:00
parent 0b5af67eb8
commit dda24eb4a8
2 changed files with 16 additions and 15 deletions

View File

@ -40,6 +40,10 @@ database_opts = [
group='DATABASE'),
cfg.DeprecatedOpt('connection',
group='sql'), ]),
cfg.StrOpt('mysql_sql_mode',
help='The SQL mode to be used for MySQL sessions '
'(default is empty, meaning do not override '
'any server-side SQL mode setting)'),
cfg.IntOpt('idle_timeout',
default=3600,
deprecated_opts=[cfg.DeprecatedOpt('sql_idle_timeout',

View File

@ -567,7 +567,7 @@ def _raise_if_db_connection_lost(error, engine):
raise exception.DBConnectionError(error)
def create_engine(sql_connection, sqlite_fk=False,
def create_engine(sql_connection, sqlite_fk=False, mysql_sql_mode=None,
mysql_traditional_mode=False, idle_timeout=3600,
connection_debug=0, max_pool_size=None, max_overflow=None,
pool_timeout=None, sqlite_synchronous=True,
@ -612,18 +612,15 @@ def create_engine(sql_connection, sqlite_fk=False,
sqlalchemy.event.listen(engine, 'checkin', _thread_yield)
if engine.name in ['mysql', 'ibm_db_sa']:
callback = functools.partial(_ping_listener, engine)
sqlalchemy.event.listen(engine, 'checkout', callback)
ping_callback = functools.partial(_ping_listener, engine)
sqlalchemy.event.listen(engine, 'checkout', ping_callback)
if engine.name == 'mysql':
if mysql_traditional_mode:
sqlalchemy.event.listen(engine, 'checkout',
_set_mode_traditional)
else:
LOG.warning(_LW("This application has not enabled MySQL "
"traditional mode, which means silent "
"data corruption may occur. "
"Please encourage the application "
"developers to enable this mode."))
mysql_sql_mode = 'TRADITIONAL'
if mysql_sql_mode:
mode_callback = functools.partial(_set_session_sql_mode,
sql_mode=mysql_sql_mode)
sqlalchemy.event.listen(engine, 'checkout', mode_callback)
elif 'sqlite' in connection_dict.drivername:
if not sqlite_synchronous:
sqlalchemy.event.listen(engine, 'connect',
@ -763,15 +760,15 @@ class EngineFacade(object):
"""
def __init__(self, sql_connection,
sqlite_fk=False, mysql_traditional_mode=False,
sqlite_fk=False, mysql_sql_mode=None,
autocommit=True, expire_on_commit=False, **kwargs):
"""Initialize engine and sessionmaker instances.
:param sqlite_fk: enable foreign keys in SQLite
:type sqlite_fk: bool
:param mysql_traditional_mode: enable traditional mode in MySQL
:type mysql_traditional_mode: bool
:param mysql_sql_mode: set SQL mode in MySQL
:type mysql_sql_mode: string
:param autocommit: use autocommit mode for created Session instances
:type autocommit: bool
@ -808,7 +805,7 @@ class EngineFacade(object):
self._engine = create_engine(
sql_connection=sql_connection,
sqlite_fk=sqlite_fk,
mysql_traditional_mode=mysql_traditional_mode,
mysql_sql_mode=mysql_sql_mode,
idle_timeout=kwargs.get('idle_timeout', 3600),
connection_debug=kwargs.get('connection_debug', 0),
max_pool_size=kwargs.get('max_pool_size'),