From 851883e1be757f0ba9446653dd069ebb94ee8a59 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Wed, 4 Jun 2014 15:24:34 -0700 Subject: [PATCH] Allow the mysql mode to be more than just TRADITIONAL To make it easier to later move to oslo.db match there ability to set a different mysql mode (this will default, unless configured explicitly off/differently to TRADITIONAL). To ensure that we retain backwards compatibility the prior existence of 'mysql_traditional_mode' as a boolean option will by default set the mode to TRADITIONAL, and a new configuration option 'mysql_sql_mode' can be used to provide a secondary overriding mode that will be used instead (incase someone wants to use something other than TRADITIONAL). Closes-Bug: 1326568 Change-Id: Ide34c27b12c26030c8842f3f4b0fcca43ce783a7 --- .../persistence/backends/impl_sqlalchemy.py | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/taskflow/persistence/backends/impl_sqlalchemy.py b/taskflow/persistence/backends/impl_sqlalchemy.py index 2f2cffcb..bcbadab1 100644 --- a/taskflow/persistence/backends/impl_sqlalchemy.py +++ b/taskflow/persistence/backends/impl_sqlalchemy.py @@ -21,6 +21,7 @@ from __future__ import absolute_import import contextlib import copy +import functools import logging import time @@ -121,15 +122,19 @@ def _thread_yield(dbapi_con, con_record): time.sleep(0) -def _set_mode_traditional(dbapi_con, con_record, connection_proxy): - """Set engine mode to 'traditional'. +def _set_sql_mode(sql_mode, dbapi_con, connection_rec): + """Set the sql_mode session variable. - Required to prevent silent truncates at insert or update operations - under MySQL. By default MySQL truncates inserted string if it longer - than a declared field just with warning. That is fraught with data - corruption. + MySQL supports several server modes. The default is None, but sessions + may choose to enable server modes like TRADITIONAL, ANSI, + several STRICT_* modes and others. + + Note: passing in '' (empty string) for sql_mode clears + the SQL mode for the session, overriding a potentially set + server default. """ - dbapi_con.cursor().execute("SET SESSION sql_mode = TRADITIONAL;") + cursor = dbapi_con.cursor() + cursor.execute("SET SESSION sql_mode = %s", [sql_mode]) def _ping_listener(dbapi_conn, connection_rec, connection_proxy): @@ -200,8 +205,14 @@ class SQLAlchemyBackend(base.Backend): if 'mysql' in e_url.drivername: if misc.as_bool(conf.pop('checkout_ping', True)): sa.event.listen(engine, 'checkout', _ping_listener) + mode = None if misc.as_bool(conf.pop('mysql_traditional_mode', True)): - sa.event.listen(engine, 'checkout', _set_mode_traditional) + mode = 'TRADITIONAL' + if 'mysql_sql_mode' in conf: + mode = conf.pop('mysql_sql_mode') + if mode is not None: + sa.event.listen(engine, 'connect', + functools.partial(_set_sql_mode, mode)) return engine @property