From: Mike Bayer Date: Wed, 4 Oct 2017 20:01:33 +0000 (-0400) Subject: Accommodate for mariadb 10.2 function reflection style X-Git-Tag: rel_0_9_6~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c2745d4790b60ab7c5c0dd3a4484f5004e4fdb35;p=thirdparty%2Fsqlalchemy%2Falembic.git Accommodate for mariadb 10.2 function reflection style Fixed bug where server default comparison of CURRENT_TIMESTAMP would fail on MariaDB 10.2 due to a change in how the function is represented by the database during reflection. Also implement mariadb 10.2 checks from SQLAlchemy to skip other CHECK contraint related tests that can't pass. Change-Id: Id77b527d3215d06e2f44a6cddeb77583e5b39101 Fixes: #455 --- diff --git a/alembic/ddl/mysql.py b/alembic/ddl/mysql.py index 3af4fa65..aff7561a 100644 --- a/alembic/ddl/mysql.py +++ b/alembic/ddl/mysql.py @@ -11,6 +11,7 @@ from .base import ColumnNullable, ColumnName, ColumnDefault, \ from .base import alter_table from ..autogenerate import compare from ..util.sqla_compat import _is_type_bound, sqla_100 +import re class MySQLImpl(DefaultImpl): @@ -94,6 +95,16 @@ class MySQLImpl(DefaultImpl): not rendered_metadata_default and \ rendered_inspector_default == "'0'": return False + elif rendered_inspector_default and rendered_metadata_default: + # adjust for "function()" vs. "FUNCTION" + return ( + re.sub( + r'(.*)(\(\))?$', '\1', + rendered_inspector_default.lower()) != + re.sub( + r'(.*)(\(\))?$', '\1', + rendered_metadata_default.lower()) + ) else: return rendered_inspector_default != rendered_metadata_default diff --git a/alembic/util/sqla_compat.py b/alembic/util/sqla_compat.py index e0507f89..b90316a5 100644 --- a/alembic/util/sqla_compat.py +++ b/alembic/util/sqla_compat.py @@ -180,3 +180,14 @@ def _get_index_final_name(dialect, idx): return dialect.ddl_compiler(dialect, None)._prepared_index_name(idx) else: return idx.name + + +def _is_mariadb(mysql_dialect): + return 'MariaDB' in mysql_dialect.server_version_info + + +def _mariadb_normalized_version_info(mysql_dialect): + if len(mysql_dialect.server_version_info) > 5: + return mysql_dialect.server_version_info[3:] + else: + return mysql_dialect.server_version_info diff --git a/docs/build/unreleased/455.rst b/docs/build/unreleased/455.rst new file mode 100644 index 00000000..8622fa36 --- /dev/null +++ b/docs/build/unreleased/455.rst @@ -0,0 +1,7 @@ +.. change:: + :tags: bug, mysql + :tickets: 455 + + Fixed bug where server default comparison of CURRENT_TIMESTAMP would fail + on MariaDB 10.2 due to a change in how the function is + represented by the database during reflection. diff --git a/tests/requirements.py b/tests/requirements.py index 2129e432..660ae21a 100644 --- a/tests/requirements.py +++ b/tests/requirements.py @@ -1,6 +1,7 @@ from alembic.testing.requirements import SuiteRequirements from alembic.testing import exclusions from alembic import util +from alembic.util import sqla_compat class DefaultRequirements(SuiteRequirements): @@ -123,3 +124,16 @@ class DefaultRequirements(SuiteRequirements): def integer_subtype_comparisons(self): """if a compare of Integer and BigInteger is supported yet.""" return exclusions.skip_if(["oracle"], "not supported by alembic impl") + + def _mariadb_102(self, config): + return exclusions.against(config, "mysql") and \ + sqla_compat._is_mariadb(config.db.dialect) and \ + sqla_compat._mariadb_normalized_version_info( + config.db.dialect) > (10, 2) + + def _mysql_not_mariadb_102(self, config): + return exclusions.against(config, "mysql") and ( + not sqla_compat._is_mariadb(config.db.dialect) or + sqla_compat._mariadb_normalized_version_info( + config.db.dialect) < (10, 2) + ) diff --git a/tests/test_batch.py b/tests/test_batch.py index 99d79560..734fc869 100644 --- a/tests/test_batch.py +++ b/tests/test_batch.py @@ -1438,6 +1438,10 @@ class BatchRoundTripMySQLTest(BatchRoundTripTest): def test_create_drop_index(self): super(BatchRoundTripMySQLTest, self).test_create_drop_index() + @exclusions.fails_if(config.requirements._mariadb_102) + def test_rename_column_boolean(self): + super(BatchRoundTripMySQLTest, self).test_rename_column_boolean() + class BatchRoundTripPostgresqlTest(BatchRoundTripTest): __only_on__ = "postgresql"