From 4e4bee514ff710ad70e37bb3758859a9b071f1b7 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Sat, 21 Dec 2013 11:12:31 -0800 Subject: [PATCH] Ensure that mysql traditional mode is enabled To avoid *silent* truncation of columns in mysql it is much safer to turn on traditional mode which behaves in the normal manner. From the mysql docs: Make MySQL behave like a "traditional" SQL database system. A simple description of this mode is "give an error instead of a warning" when inserting an incorrect value into a column. Change-Id: Ic62af8514c377d2b8c934449116498855e03d7bd --- taskflow/persistence/backends/impl_sqlalchemy.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/taskflow/persistence/backends/impl_sqlalchemy.py b/taskflow/persistence/backends/impl_sqlalchemy.py index a36747df..f1d94f12 100644 --- a/taskflow/persistence/backends/impl_sqlalchemy.py +++ b/taskflow/persistence/backends/impl_sqlalchemy.py @@ -123,6 +123,17 @@ def _thread_yield(dbapi_con, con_record): time.sleep(0) +def _set_mode_traditional(dbapi_con, con_record): + """Set engine mode to 'traditional'. + + 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. + """ + dbapi_con.cursor().execute("SET SESSION sql_mode = TRADITIONAL;") + + def _ping_listener(dbapi_conn, connection_rec, connection_proxy): """Ensures that MySQL connections checked out of the pool are alive. @@ -232,6 +243,8 @@ 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) + if misc.as_bool(conf.pop('mysql_traditional_mode', True)): + sa.event.listen(engine, 'checkout', _set_mode_traditional) try: max_retries = misc.as_int(conf.pop('max_retries', None)) except TypeError: